/day_8.clj Secret
Last active
December 9, 2020 07:37
AOC Day 8
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns day-8) | |
(def data (slurp "input/day_8.txt")) | |
(def sample-data "nop +0\nacc +1\njmp +4\nacc +3\njmp -3\nacc -99\nacc +1\njmp -4\nacc +6") | |
(defn make-cpu [] {:pc 0 :acc 0}) | |
(defn parse-ops-str [s] | |
(map (fn [[_ op n]] | |
[(keyword op) (Integer/parseInt n)]) | |
(re-seq #"(\w+) ([+-]\d+)" s))) | |
(defn execute [{:keys [pc acc] :as cpu} [op n]] | |
(case op | |
:nop (update cpu :pc inc) | |
:acc (assoc cpu :pc (inc pc) :acc (+ acc n)) | |
:jmp (update cpu :pc #(+ % n)))) | |
(defn exec-until-loop-detected [code] | |
(let [cpu (make-cpu)] | |
(loop [{:keys [pc acc] :as cpu} cpu | |
seen-op-idxs #{pc}] | |
(let [op (nth code pc) | |
cpu' (execute cpu op)] | |
(if (= (count code) (:pc cpu')) | |
[:completed cpu'] | |
(if (contains? seen-op-idxs (:pc cpu')) | |
[:halted cpu] | |
(recur cpu' (conj seen-op-idxs (:pc cpu'))))))))) | |
(comment | |
(exec-until-loop-detected (parse-ops-str data))) | |
;; part 2 | |
(defn code-variations [code] | |
(let [code (vec code)] | |
(loop [i 0] | |
(let [[op n] (nth code i) | |
alt-op (case op | |
:jmp :nop | |
:nop :jmp | |
nil)] | |
(if alt-op | |
(let [alt-code (assoc code i [alt-op n]) | |
[status cpu] (exec-until-loop-detected alt-code)] | |
(if (= status :completed) | |
cpu | |
(recur (inc i)))) | |
(recur (inc i))))))) | |
(comment | |
(code-variations (parse-ops-str data))) | |
;; part 2 redux (after looking at other answers) | |
(defn code-variations' [code] | |
(let [code (vec code)] | |
(for [i (range (count code)) | |
:let [[op n] (nth code i) | |
alt-op ({:jmp :nop, :nop :jmp} op)] | |
:when alt-op] | |
(assoc code i [alt-op n])))) | |
(comment | |
(->> (parse-ops-str data) | |
(code-variations') | |
(map exec-until-loop-detected) | |
(filter (fn [[status cpu]] (= status :completed))) | |
(first))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment