|
|
|
(require '[clojure.string :as str])
|
|
|
|
|
|
|
|
; The given program operates on a base-26 stack, either pushing or
|
|
|
|
; (conditionally) popping values. This code extracts those operations
|
|
|
|
; from the input, then works through them to determine the highest
|
|
|
|
; and lowest values that produce an output of zero.
|
|
|
|
; See the .md file in this directory for more info.
|
|
|
|
|
|
|
|
(def program (->> (slurp "./in")
|
|
|
|
str/split-lines
|
|
|
|
(map #(str/split % #"\s+"))
|
|
|
|
(partition 18)
|
|
|
|
(map (fn [step]
|
|
|
|
(if (= "1" (last (nth step 4)))
|
|
|
|
[:push (read-string (last (nth step 15)))]
|
|
|
|
[:pop (read-string (last (nth step 5)))])
|
|
|
|
))))
|
|
|
|
|
|
|
|
(defn program-index [prog] (- 14 (count prog)))
|
|
|
|
|
|
|
|
(loop [numbers (vec (repeat 2 (vec (repeat 14 0))))
|
|
|
|
stack '()
|
|
|
|
prog program]
|
|
|
|
(if-let [step (first prog)]
|
|
|
|
(if (= :push (first step))
|
|
|
|
(recur numbers
|
|
|
|
(conj stack [(program-index prog) (second step)])
|
|
|
|
(rest prog))
|
|
|
|
(let [i2 (program-index prog)
|
|
|
|
[i1 v] (first stack)
|
|
|
|
diff (+ v (second step))]
|
|
|
|
(recur
|
|
|
|
[(if (neg? diff)
|
|
|
|
(-> (first numbers) (assoc i1 9) (assoc i2 (+ 9 diff)))
|
|
|
|
(-> (first numbers) (assoc i2 9) (assoc i1 (- 9 diff))))
|
|
|
|
(if (neg? diff)
|
|
|
|
(-> (second numbers) (assoc i2 1) (assoc i1 (- 1 diff)))
|
|
|
|
(-> (second numbers) (assoc i1 1) (assoc i2 (+ 1 diff))))]
|
|
|
|
(rest stack) (rest prog))))
|
|
|
|
(println (map str/join numbers))))
|
|
|
|
|