(ns adventofcode2019.day14 [:require [adventofcode2019.lib :refer :all] [clojure.string :as str] [clojure.core.match :refer [match]]]) (defn parse-reaction [reaction-text] (let [parse-chemical (fn [text] (let [[ct chem] (str/split (str/trim text) #" ")] {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 make-graph [input] (reduce (partial merge-with merge) (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 producing consuming] (get-in (reduce-reaction graph producing consuming) [producing 0 consuming])) (defn day14 [] (let [graphed (make-graph (get-list-from-file (input-file)))] (part1 (find-lowest-exchange-rate graphed "FUEL" "ORE")) #_(part2)))