-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathday25.clj
82 lines (68 loc) · 2.16 KB
/
day25.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
(ns day25
(:require aoc
day12
[clojure.core.match :refer [match]]))
(defn run-instruction [{:keys [instrs len line regs] :as state}]
(if-not (< -1 line len)
(assoc state :done? true)
(match (instrs line)
[:cpy what where]
(cond
(= line 1)
(-> state
(update-in [:regs :d] + (* 7 362))
(update :line + 7))
(= line 12)
(-> state
(update-in [:regs :a] + (quot (regs :b) 2))
(assoc-in [:regs :c] (- 2 (rem (regs :b) 2)))
(assoc-in [:regs :b] 0)
(update :line + 8))
:else
(-> state
(update :line inc)
(assoc-in [:regs where] (or (regs what) what))))
[:jnz val jump]
(if (zero? (or (regs val) val))
(update state :line inc)
(assoc state :line (+ line (or (regs jump) jump))))
[:inc reg nil]
(-> state
(update :line inc)
(update-in [:regs reg] inc))
[:dec reg nil]
(-> state
(update :line inc)
(update-in [:regs reg] dec))
[:out val nil]
(let [current (or (regs val) val)
prev (peek (:out state))]
(if (or (not (#{0 1} current))
(= prev current))
(-> state
(assoc :done? true))
(-> state
(update :out conj current)
(update :line inc)))))))
(defn run-computer [state]
(loop [initial-state state
a 0]
(let [state (update initial-state :regs conj {:a a})
res (loop [state state]
(if (or (:done? state)
(> (count (:out state)) 10))
(:out state)
(recur (run-instruction state))))]
(if (> (count res) 10)
a
(recur initial-state (inc a))))))
(defn solve [input]
(let [instructions (vec (aoc/read-input input day12/parse-line))
init-state {:instrs instructions
:len (count instructions)
:line 0
:done? false
:out []
:regs {:b 0 :c 0 :d 0}}]
(run-computer init-state)))
(solve 25)