]>
Commit | Line | Data |
---|---|---|
e26daef4 | 1 | (ns adventofcode2019.day14 |
49dee54b JK |
2 | [:require [adventofcode2019.lib :refer :all] |
3 | [clojure.string :as str] | |
4 | [clojure.core.match :refer [match]]]) | |
e26daef4 JK |
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))] | |
49dee54b | 12 | {out-chem [(reduce merge {} (map parse-chemical (str/split inputs #","))) out-ct]})) |
e26daef4 JK |
13 | |
14 | (defn make-graph [input] | |
15 | (reduce (partial merge-with merge) | |
49dee54b JK |
16 | (map parse-reaction input))) |
17 | ||
18 | (defn reduce-reaction [graph producing consuming] | |
0ebe675a JK |
19 | (let [consuming (into #{} (if (coll? consuming) consuming [consuming])) |
20 | [inputs moles] (graph producing) | |
49dee54b JK |
21 | in-chems (keys inputs) |
22 | replace-term (fn [chem] | |
0ebe675a | 23 | (if (or (contains? consuming chem) |
49dee54b JK |
24 | (neg? (second (graph chem)))) |
25 | {chem (inputs chem)} | |
26 | (let [ch-req (inputs chem) | |
27 | [ch-in ch-mo] (graph chem) | |
28 | conversion (int (Math/ceil (/ ch-req ch-mo)))] | |
29 | (assoc (mmap (partial * conversion) ch-in) | |
30 | chem (- ch-req (* ch-mo conversion)))))) | |
0ebe675a | 31 | check-reduced (fn [[ch ct]] (and (not (contains? consuming ch)) (pos? ct))) |
49dee54b JK |
32 | reduced-inputs (reduce (partial merge-with +) |
33 | (map replace-term in-chems)) | |
34 | new-graph (assoc graph producing [reduced-inputs moles])] | |
35 | (if (some check-reduced reduced-inputs) | |
36 | (recur new-graph producing consuming) | |
37 | new-graph))) | |
e26daef4 | 38 | |
49dee54b JK |
39 | (defn find-lowest-exchange-rate [graph producing consuming] |
40 | (get-in (reduce-reaction graph producing consuming) | |
41 | [producing 0 consuming])) | |
e26daef4 | 42 | |
0ebe675a JK |
43 | (defn produce-with [graph producing consuming cargo] |
44 | (println graph producing consuming cargo) | |
45 | (let [cheapest-prod (get-in graph [producing 0]) | |
46 | exchange-rate (cheapest-prod consuming) | |
47 | base-times (quot cargo exchange-rate) | |
48 | extra-cargo (mod cargo exchange-rate) | |
49 | extra-resources (assoc (->> cheapest-prod | |
50 | (filter (comp neg? second)) | |
51 | (map (fn [[chem mole]] | |
52 | [chem (* -1 base-times mole)])) | |
53 | (into {})) consuming extra-cargo) | |
54 | rewrite-with (into #{} (keys extra-resources)) | |
55 | second-chance (reduce-reaction graph producing rewrite-with) | |
56 | recursive-times (map (fn [[chem ct]] | |
57 | (let [er (- (get-in second-chance [producing 0 chem]))] | |
58 | (println chem ct er) | |
59 | (quot ct er))) | |
60 | extra-resources)] | |
61 | recursive-times)) | |
62 | ||
63 | (defn maximize-output [graph producing consuming cargo] | |
64 | (produce-with (reduce-reaction graph producing consuming) | |
65 | producing consuming cargo)) | |
66 | ||
e26daef4 JK |
67 | (defn day14 [] |
68 | (let [graphed (make-graph (get-list-from-file (input-file)))] | |
69 | (part1 (find-lowest-exchange-rate graphed "FUEL" "ORE")) | |
0ebe675a | 70 | (part2 (maximize-output graphed "FUEL" "ORE" 1000000000000)))) |