1 (ns adventofcode2019.day07
2 [:require [adventofcode2019.lib :refer :all]
3 [clojure.string :as str]
4 [clojure.math.combinatorics :as combo]
5 [clojure.core.async :as a]])
7 ;; 0: function args&mem -> [mem (ctr -> ctr)]
9 (defn decode-op [opcode in out]
10 (let [str-code (format "%05d" opcode)
11 [f3 f2 f1] (map #(= \1 %) (take 3 str-code))
12 op (parse-int (str/join (drop 3 str-code)))
13 with-flags (fn [[f ac]]
16 2 #(f ((if f1 identity %1) %2)
17 ((if f2 identity %1) %3) %1)
18 3 #(f ((if f1 identity %1) %2)
19 ((if f2 identity %1) %3) %4 %1)) ac])]
23 [(assoc mem c (+ a b)) #(+ % 4)])
26 [(assoc mem c (* a b)) #(+ % 4)])
29 [(assoc mem a (a/<!! in)) #(+ % 2)])
36 [mem (if (not= a 0) (constantly b) #(+ % 3))])
39 [mem (if (= a 0) (constantly b) #(+ % 3))])
42 [(assoc mem c (if (< a b) 1 0)) #(+ % 4)])
45 [(assoc mem c (if (= a b) 1 0)) #(+ % 4)])
48 (defn perform-operation [program counter in out]
49 (let [opcode (program counter)
50 [operation arg-ct] (decode-op opcode in out)
51 args (->> (iterate inc counter)
55 (let [[program ctr-update] (apply operation program args)]
56 [program (ctr-update counter)])))
60 (intcode program nil nil))
62 (loop [[program counter] [program 0]]
63 (let [opcode (program counter)]
66 (recur (perform-operation program counter in out)))))))
69 (let [input (mapv parse-int (get-list-from-file (input-file) #","))
70 phase-settings-1 (combo/permutations [0 1 2 3 4])
71 phase-settings-2 (combo/permutations [5 6 7 8 9])
72 channels (->> #(a/chan 2)
75 all-outputs-1 (for [settings phase-settings-1]
76 (do (doall (map a/>!! channels settings))
77 (a/>!! (first channels) 0)
78 (doall (map intcode (repeat 5 input) channels (rest channels)))
79 (a/<!! (first channels))))
80 all-outputs-2 (for [settings phase-settings-2]
81 (do (doall (map a/>!! channels settings))
82 (a/>!! (first channels) 0)
83 (a/<!! (last (for [[prog in out]
84 (map vector (repeat 5 input) channels (rest channels))]
86 (intcode prog in out)))))
87 (a/<!! (first channels))))]
88 (part1 (apply max all-outputs-1))
89 (part2 (apply max all-outputs-2))))