1 (ns adventofcode2019.day14
2 [:require [adventofcode2019.lib :refer :all]
3 [clojure.string :as str]
4 [clojure.core.match :refer [match]]])
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]}))
14 (defn make-graph [input]
15 (reduce (partial merge-with merge)
16 (map parse-reaction input)))
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))))
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)
38 (defn find-lowest-exchange-rate [graph producing consuming]
39 (get-in (reduce-reaction graph producing consuming)
40 [producing 0 consuming]))
43 (let [graphed (make-graph (get-list-from-file (input-file)))]
44 (part1 (find-lowest-exchange-rate graphed "FUEL" "ORE"))