aoc

ref: master

2020/src/aoc/day08.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
85
86
87
88
89
90
91
92
93
94
95
96
(ns aoc.day08
  (:require [clojure.java.io :as io])

(def example "nop +0
acc +1
jmp +4
acc +3
jmp -3
acc -99
acc +1
jmp -4
acc +6")

(def example-terminating "nop +0
acc +1
jmp +4
acc +3
jmp -3
acc -99
acc +1
nop -4
acc +6")

(defn parse-instruction [s]
  (let [[op n] (clojure.string/split s #" ")]
    (assoc {}
           :op (keyword op)
           :value (read-string n))))

(defn accumulate [acc value]
  (if (>= value 0)
    (+ acc value)
    (- acc value)))

(defn step [acc index {:keys [op value]}]
  (case op
    :acc [(+ acc value) (inc index)]
    :jmp [acc (+ index value)]
    :nop [acc (inc index)]))

(defn run-computer [coll]
  (loop [index 0
         acc 0
         log #{}]
    (if (contains? log index)
      acc
      (let [[new-acc new-index] (step acc index (nth coll index))]
        (recur new-index new-acc (conj log index))))))

(defn run-computer-2 [coll]
  (loop [index 0
         acc 0
         log #{}]
    (cond
      (contains? log index) :infinite-loop
      (= index (count coll)) acc
      :else (let [[new-acc new-index] (step acc index (nth coll index))]
              (recur new-index new-acc (conj log index))))))


;; ----------------------------------------------------------------------------- 

(defn read-input []
  (->> (slurp (io/resource "input08.txt"))
       clojure.string/split-lines
       (map parse-instruction)))

(defn compute-1 [input]
  (run-computer input))

(defn reverse-it [op]
  ;; LOL
  (get {:jmp :nop
        :nop :jmp}
       op))

(defn compute-2 [input]
  (let [input (vec input)
        indexes (range (count input))
        possibilities (map (fn [i]
                          (let [{:keys [op]} (nth input i)]
                            (if (contains? #{:jmp :nop} op)
                              (assoc-in input [i :op] (reverse-it op))
                              input)))
                        indexes)]
    (->> possibilities
         (map run-computer-2)
         (remove #(= :infinite-loop %))
         first)))

(defn main []
  (let [input (read-input)]
    (println (compute-1 input))
    (println (compute-2 input))))

(main)