Commit | Line | Data |
---|---|---|
e26daef4 JK |
1 | (ns adventofcode2019.day14 |
2 | [:require [adventofcode2019.lib :refer :all] | |
3 | [adventofcode2019.intcode :as i] | |
4 | [clojure.string :as str] | |
5 | [clojure.set :as set] | |
6 | [clojure.core.match :refer [match]] | |
7 | [clojure.math.combinatorics :as combo]]) | |
8 | ||
9 | (defn parse-reaction [reaction-text] | |
10 | (let [parse-chemical (fn [text] | |
11 | (let [[ct chem] (str/split (str/trim text) #" ")] | |
12 | {chem (parse-int ct)})) | |
13 | [inputs output] (str/split reaction-text #"=>") | |
14 | [[out-chem out-ct]] (seq (parse-chemical output))] | |
15 | {out-chem {(reduce merge {} (map parse-chemical (str/split inputs #","))) out-ct}})) | |
16 | ||
17 | (defn normalize-reaction [reaction] | |
18 | (let [[output] (keys reaction) | |
19 | arrows (reaction output) | |
20 | inputs (keys arrows) | |
21 | normalize-arrow (fn [[akey aval]] | |
22 | {(reduce-kv (fn [m k v] | |
23 | (assoc m k (rationalize (/ v aval)))) | |
24 | {} akey) 1})] | |
25 | {output (reduce merge {} (map normalize-arrow arrows))})) | |
26 | ||
27 | (defn make-graph [input] | |
28 | (reduce (partial merge-with merge) | |
29 | (map (comp normalize-reaction parse-reaction) input))) | |
30 | ||
31 | (defn find-lowest-exchange-rate [graph start end] | |
32 | (let [reactions (graph start) | |
33 | input-lists (keys reactions) | |
34 | input-chems (mapv keys input-lists) | |
35 | trade (fn [recv exch] | |
36 | (let [rx (if (ratio? exch) (numerator exch) exch) | |
37 | xc (if (ratio? exch) (denominator exch) 1) | |
38 | units (int (Math/ceil (/ recv xc)))] | |
39 | (* units rx))) | |
40 | find-terminal #(match [%] | |
41 | [({end v} :only [end])] v | |
42 | :else nil) | |
43 | calculate-er (fn [[chem ct]] | |
44 | (trade ct (find-lowest-exchange-rate graph chem end))) | |
45 | reaction-er #(reduce + (map calculate-er %))] | |
46 | (if (some #{[end]} input-chems) | |
47 | (->> input-lists | |
48 | (map find-terminal) | |
49 | (remove nil?) | |
50 | (reduce min)) | |
51 | (->> input-lists | |
52 | (map reaction-er) | |
53 | (reduce min))))) | |
54 | ||
55 | (defn day14 [] | |
56 | (let [graphed (make-graph (get-list-from-file (input-file)))] | |
57 | (part1 (find-lowest-exchange-rate graphed "FUEL" "ORE")) | |
58 | #_(part2))) |