X-Git-Url: http://git.jkinsey.net/?p=adventofcode2019.git;a=blobdiff_plain;f=src%2Fadventofcode2019%2Fday14.clj;fp=src%2Fadventofcode2019%2Fday14.clj;h=e2aae3e11000ebd9e14f8920caec7d10234c9fea;hp=e0e9b26402f7ae9ad1fa8153341bb20151409efa;hb=49dee54b66741b6ad08ef15fb46e15310edbd765;hpb=e26daef486624d7197207d38b601a4e505e6ef26 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)))]