X-Git-Url: http://git.jkinsey.net/?p=adventofcode2019.git;a=blobdiff_plain;f=src%2Fadventofcode2019%2Fday14.clj;fp=src%2Fadventofcode2019%2Fday14.clj;h=e0e9b26402f7ae9ad1fa8153341bb20151409efa;hp=0000000000000000000000000000000000000000;hb=e26daef486624d7197207d38b601a4e505e6ef26;hpb=15f6c3bbb172e88ff9a6d393057abc40db9373bf diff --git a/src/adventofcode2019/day14.clj b/src/adventofcode2019/day14.clj new file mode 100644 index 0000000..e0e9b26 --- /dev/null +++ b/src/adventofcode2019/day14.clj @@ -0,0 +1,58 @@ +(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]]) + +(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 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))})) + +(defn make-graph [input] + (reduce (partial merge-with merge) + (map (comp normalize-reaction parse-reaction) input))) + +(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 day14 [] + (let [graphed (make-graph (get-list-from-file (input-file)))] + (part1 (find-lowest-exchange-rate graphed "FUEL" "ORE")) + #_(part2)))