| 1 | (ns adventofcode2019.day14 |
| 2 | [:require [adventofcode2019.lib :refer :all] |
| 3 | [clojure.string :as str] |
| 4 | [clojure.core.match :refer [match]]]) |
| 5 | |
| 6 | (defn parse-reaction [reaction-text] |
| 7 | (let [parse-chemical (fn [text] |
| 8 | (let [[ct chem] (str/split (str/trim text) #" ")] |
| 9 | {chem (parse-int ct)})) |
| 10 | [inputs output] (str/split reaction-text #"=>") |
| 11 | [[out-chem out-ct]] (seq (parse-chemical output))] |
| 12 | {out-chem [(reduce merge {} (map parse-chemical (str/split inputs #","))) out-ct]})) |
| 13 | |
| 14 | (defn make-graph [input] |
| 15 | (reduce (partial merge-with merge) |
| 16 | (map parse-reaction input))) |
| 17 | |
| 18 | (defn reduce-reaction [graph producing consuming] |
| 19 | (let [[inputs moles] (graph producing) |
| 20 | in-chems (keys inputs) |
| 21 | replace-term (fn [chem] |
| 22 | (if (or (= chem consuming) |
| 23 | (neg? (second (graph chem)))) |
| 24 | {chem (inputs chem)} |
| 25 | (let [ch-req (inputs chem) |
| 26 | [ch-in ch-mo] (graph chem) |
| 27 | conversion (int (Math/ceil (/ ch-req ch-mo)))] |
| 28 | (assoc (mmap (partial * conversion) ch-in) |
| 29 | chem (- ch-req (* ch-mo conversion)))))) |
| 30 | check-reduced (fn [[ch ct]] (and (not= ch consuming) (pos? ct))) |
| 31 | reduced-inputs (reduce (partial merge-with +) |
| 32 | (map replace-term in-chems)) |
| 33 | new-graph (assoc graph producing [reduced-inputs moles])] |
| 34 | (if (some check-reduced reduced-inputs) |
| 35 | (recur new-graph producing consuming) |
| 36 | new-graph))) |
| 37 | |
| 38 | (defn find-lowest-exchange-rate [graph producing consuming] |
| 39 | (get-in (reduce-reaction graph producing consuming) |
| 40 | [producing 0 consuming])) |
| 41 | |
| 42 | (defn day14 [] |
| 43 | (let [graphed (make-graph (get-list-from-file (input-file)))] |
| 44 | (part1 (find-lowest-exchange-rate graphed "FUEL" "ORE")) |
| 45 | #_(part2))) |