From: Jack Kinsey Date: Thu, 19 Dec 2019 17:12:42 +0000 (-0500) Subject: Rework day14pt1 X-Git-Url: http://git.jkinsey.net/?p=adventofcode2019.git;a=commitdiff_plain;h=49dee54b66741b6ad08ef15fb46e15310edbd765 Rework day14pt1 day14pt1 was tested failing, so it's been reworked. Local tests are green, but this version hasn't been checked against AoC. Also, beef up local testing. --- diff --git a/src/adventofcode2019/day14.clj b/src/adventofcode2019/day14.clj index e0e9b26..e2aae3e 100644 --- a/src/adventofcode2019/day14.clj +++ b/src/adventofcode2019/day14.clj @@ -1,10 +1,7 @@ (ns adventofcode2019.day14 - [:require [adventofcode2019.lib :refer :all] - [adventofcode2019.intcode :as i] - [clojure.string :as str] - [clojure.set :as set] - [clojure.core.match :refer [match]] - [clojure.math.combinatorics :as combo]]) + [:require [adventofcode2019.lib :refer :all] + [clojure.string :as str] + [clojure.core.match :refer [match]]]) (defn parse-reaction [reaction-text] (let [parse-chemical (fn [text] @@ -12,45 +9,35 @@ {chem (parse-int ct)})) [inputs output] (str/split reaction-text #"=>") [[out-chem out-ct]] (seq (parse-chemical output))] - {out-chem {(reduce merge {} (map parse-chemical (str/split inputs #","))) out-ct}})) - -(defn normalize-reaction [reaction] - (let [[output] (keys reaction) - arrows (reaction output) - inputs (keys arrows) - normalize-arrow (fn [[akey aval]] - {(reduce-kv (fn [m k v] - (assoc m k (rationalize (/ v aval)))) - {} akey) 1})] - {output (reduce merge {} (map normalize-arrow arrows))})) + {out-chem [(reduce merge {} (map parse-chemical (str/split inputs #","))) out-ct]})) (defn make-graph [input] (reduce (partial merge-with merge) - (map (comp normalize-reaction parse-reaction) input))) + (map parse-reaction input))) + +(defn reduce-reaction [graph producing consuming] + (let [[inputs moles] (graph producing) + in-chems (keys inputs) + replace-term (fn [chem] + (if (or (= chem consuming) + (neg? (second (graph chem)))) + {chem (inputs chem)} + (let [ch-req (inputs chem) + [ch-in ch-mo] (graph chem) + conversion (int (Math/ceil (/ ch-req ch-mo)))] + (assoc (mmap (partial * conversion) ch-in) + chem (- ch-req (* ch-mo conversion)))))) + check-reduced (fn [[ch ct]] (and (not= ch consuming) (pos? ct))) + reduced-inputs (reduce (partial merge-with +) + (map replace-term in-chems)) + new-graph (assoc graph producing [reduced-inputs moles])] + (if (some check-reduced reduced-inputs) + (recur new-graph producing consuming) + new-graph))) -(defn find-lowest-exchange-rate [graph start end] - (let [reactions (graph start) - input-lists (keys reactions) - input-chems (mapv keys input-lists) - trade (fn [recv exch] - (let [rx (if (ratio? exch) (numerator exch) exch) - xc (if (ratio? exch) (denominator exch) 1) - units (int (Math/ceil (/ recv xc)))] - (* units rx))) - find-terminal #(match [%] - [({end v} :only [end])] v - :else nil) - calculate-er (fn [[chem ct]] - (trade ct (find-lowest-exchange-rate graph chem end))) - reaction-er #(reduce + (map calculate-er %))] - (if (some #{[end]} input-chems) - (->> input-lists - (map find-terminal) - (remove nil?) - (reduce min)) - (->> input-lists - (map reaction-er) - (reduce min))))) +(defn find-lowest-exchange-rate [graph producing consuming] + (get-in (reduce-reaction graph producing consuming) + [producing 0 consuming])) (defn day14 [] (let [graphed (make-graph (get-list-from-file (input-file)))] diff --git a/src/adventofcode2019/lib.clj b/src/adventofcode2019/lib.clj index 890ddf5..4b424a8 100644 --- a/src/adventofcode2019/lib.clj +++ b/src/adventofcode2019/lib.clj @@ -24,6 +24,9 @@ (+ (Math/abs (- ax bx)) (Math/abs (- ay by)))) +(defn mmap [f m] + (reduce-kv #(assoc %1 %2 (f %3)) {} m)) + (def part1 #(println (str "Part 1: " %))) (def part2 diff --git a/test/adventofcode2019/core_test.clj b/test/adventofcode2019/core_test.clj index d571560..1b5e647 100644 --- a/test/adventofcode2019/core_test.clj +++ b/test/adventofcode2019/core_test.clj @@ -1,7 +1,3 @@ (ns adventofcode2019.core-test (:require [clojure.test :refer :all] [adventofcode2019.core :refer :all])) - -(deftest a-test - (testing "FIXME, I fail." - (is (= 0 1)))) diff --git a/test/adventofcode2019/day14_test.clj b/test/adventofcode2019/day14_test.clj index 1a6bd86..7e99dcc 100644 --- a/test/adventofcode2019/day14_test.clj +++ b/test/adventofcode2019/day14_test.clj @@ -2,36 +2,86 @@ (:require [clojure.test :refer :all] [adventofcode2019.day14 :refer :all])) -(deftest check-make-graph - (is (= (make-graph ["3 ORE => 2 ABC" +(deftest test-make-graph + (is (= (make-graph ["3 ORE => 2 ABC" "3 ABC => 1 FUEL"]) - {"ABC" {{"ORE" 3/2} 1} - "FUEL" {{"ABC" 3} 1}}))) + {"ABC" [{"ORE" 3} 2] + "FUEL" [{"ABC" 3} 1]}))) -(deftest simple-exchange - (is (= 3 (find-lowest-exchange-rate {"FUEL" {{"ORE" 1, "ABC" 2, "DEF" 3} 1 - {"ORE" 3} 1 - {"GHI" 5/2} 1}} - "FUEL" "ORE")))) +(deftest test-reduce + (is (= (reduce-reaction (make-graph ["9 ORE => 2 A" + "8 ORE => 3 B" + "7 ORE => 5 C" + "3 A, 4 B => 1 AB" + "5 B, 7 C => 1 BC" + "4 C, 1 A => 1 CA" + "2 AB, 3 BC, 4 CA => 1 FUEL"]) + "FUEL", "ORE") + {"A" [{"ORE" 9} 2] + "B" [{"ORE" 8} 3] + "C" [{"ORE" 7} 5] + "AB" [{"A" 3, "B" 4} 1] + "BC" [{"B" 5, "C" 7} 1] + "CA" [{"C" 4, "A" 1} 1] + "FUEL" [{"ORE" 165, "A" 0 + "B" -1, "AB" 0 + "C" -3, "BC" 0 + "CA" 0} 1]}))) -(deftest trading-up - (is (= 6 (find-lowest-exchange-rate (make-graph ["3 ORE => 2 ABC" - "3 ABC => 1 FUEL"]) - "FUEL" "ORE")))) - -(deftest complicated-exchange - (is (= 2 (find-lowest-exchange-rate (make-graph ["3 ORE => 2 ABC" - "3 ABC => 1 FUEL" - "2 ORE => 1 CDE" - "1 CDE => 1 FUEL"]) - "FUEL" "ORE")))) - -(deftest very-tricky-exchange - (is (= 3 (find-lowest-exchange-rate (make-graph ["3 ORE => 2 ABC" - "3 ABC => 1 FUEL" - "4 ORE => 1 CDE" - "1 CDE => 1 FUEL" - "3 ORE => 2 FGH" - "1 FGH => 1 IJK" - "1 IJK => 1 FUEL"]) - "FUEL" "ORE")))) +(deftest examples + (is (= 31 (find-lowest-exchange-rate (make-graph ["10 ORE => 10 A" + "1 ORE => 1 B" + "7 A, 1 B => 1 C" + "7 A, 1 C => 1 D" + "7 A, 1 D => 1 E" + "7 A, 1 E => 1 FUEL"]) + "FUEL", "ORE"))) + (is (= 165 (find-lowest-exchange-rate (make-graph ["9 ORE => 2 A" + "8 ORE => 3 B" + "7 ORE => 5 C" + "3 A, 4 B => 1 AB" + "5 B, 7 C => 1 BC" + "4 C, 1 A => 1 CA" + "2 AB, 3 BC, 4 CA => 1 FUEL"]) + "FUEL", "ORE"))) + (is (= 13312 (find-lowest-exchange-rate (make-graph ["157 ORE => 5 NZVS" + "165 ORE => 6 DCFZ" + "44 XJWVT, 5 KHKGT, 1 QDVJ, 29 NZVS, 9 GPVTF, 48 HKGWZ => 1 FUEL" + "12 HKGWZ, 1 GPVTF, 8 PSHF => 9 QDVJ" + "179 ORE => 7 PSHF" + "177 ORE => 5 HKGWZ" + "7 DCFZ, 7 PSHF => 2 XJWVT" + "165 ORE => 2 GPVTF" + "3 DCFZ, 7 NZVS, 5 HKGWZ, 10 PSHF => 8 KHKGT"]) + "FUEL", "ORE"))) + (is (= 180697 (find-lowest-exchange-rate (make-graph ["2 VPVL, 7 FWMGM, 2 CXFTF, 11 MNCFX => 1 STKFG" + "17 NVRVD, 3 JNWZP => 8 VPVL" + "53 STKFG, 6 MNCFX, 46 VJHF, 81 HVMC, 68 CXFTF, 25 GNMV => 1 FUEL" + "22 VJHF, 37 MNCFX => 5 FWMGM" + "139 ORE => 4 NVRVD" + "144 ORE => 7 JNWZP" + "5 MNCFX, 7 RFSQX, 2 FWMGM, 2 VPVL, 19 CXFTF => 3 HVMC" + "5 VJHF, 7 MNCFX, 9 VPVL, 37 CXFTF => 6 GNMV" + "145 ORE => 6 MNCFX" + "1 NVRVD => 8 CXFTF" + "1 VJHF, 6 MNCFX => 4 RFSQX" + "176 ORE => 6 VJHF"]) + "FUEL", "ORE"))) + (is (= 2210736 (find-lowest-exchange-rate (make-graph ["171 ORE => 8 CNZTR" + "7 ZLQW, 3 BMBT, 9 XCVML, 26 XMNCP, 1 WPTQ, 2 MZWV, 1 RJRHP => 4 PLWSL" + "114 ORE => 4 BHXH" + "14 VRPVC => 6 BMBT" + "6 BHXH, 18 KTJDG, 12 WPTQ, 7 PLWSL, 31 FHTLT, 37 ZDVW => 1 FUEL" + "6 WPTQ, 2 BMBT, 8 ZLQW, 18 KTJDG, 1 XMNCP, 6 MZWV, 1 RJRHP => 6 FHTLT" + "15 XDBXC, 2 LTCX, 1 VRPVC => 6 ZLQW" + "13 WPTQ, 10 LTCX, 3 RJRHP, 14 XMNCP, 2 MZWV, 1 ZLQW => 1 ZDVW" + "5 BMBT => 4 WPTQ" + "189 ORE => 9 KTJDG" + "1 MZWV, 17 XDBXC, 3 XCVML => 2 XMNCP" + "12 VRPVC, 27 CNZTR => 2 XDBXC" + "15 KTJDG, 12 BHXH => 5 XCVML" + "3 BHXH, 2 VRPVC => 7 MZWV" + "121 ORE => 7 VRPVC" + "7 XCVML => 6 RJRHP" + "5 BHXH, 4 VRPVC => 5 LTCX"]) + "FUEL", "ORE")))) diff --git a/test/adventofcode2019/template_test.clj b/test/adventofcode2019/template_test.clj new file mode 100644 index 0000000..bf3ebec --- /dev/null +++ b/test/adventofcode2019/template_test.clj @@ -0,0 +1,6 @@ +(ns adventofcode2019.day00-test + (:require [clojure.test :refer :all] + [adventofcode2019.day00 :refer :all])) + +(deftest examples + (is (= 0 1)))