-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathday23.clj
84 lines (68 loc) · 1.96 KB
/
day23.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
83
84
(ns day23
(:require aoc
day12
[clojure.core.match :refer [match]]))
(defn toggle [[a b c]]
[({:cpy :jnz
:jnz :cpy
:inc :dec
:dec :inc
:tgl :inc} a)
b
c])
(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 4)
(-> state
(update-in [:regs :a] + (* (regs :b) (regs :d)))
(assoc-in [:regs :c] 0)
(assoc-in [:regs :d] 0)
(update :line + 6))
(= line 20)
(-> state
(update-in [:regs :a] + (* 87 (regs :c)))
(update :line + 6))
: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))
[:tgl reg nil]
(let [jump (regs reg)
new-line (+ line jump)]
(-> state
(update :line inc)
(#(if (< -1 new-line len)
(assoc-in % [:instrs new-line] (toggle (instrs new-line)))
%)))))))
(defn run-computer [{:keys [done?] :as state}]
(if done?
(-> state :regs :a)
(recur (run-instruction state))))
(defn solve [input]
(let [instructions (vec (aoc/read-input input day12/parse-line))
init-state {:instrs instructions
:len (count instructions)
:line 0
:done? false
:regs {:b 0 :c 0 :d 0}}]
(for [a [7 12]]
(-> init-state
(update :regs conj {:a a})
run-computer))))
(solve 23)