From 66ed0b9d27850dc653abc8baa75884f3de311bfa Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sun, 26 Dec 2021 08:41:42 -0500 Subject: [PATCH] day24: solve using code --- day24/checker.clj | 47 +++++++++++++++++++++++++++++ day24/partboth.clj | 74 +++++++++++++++++++++------------------------- 2 files changed, 81 insertions(+), 40 deletions(-) create mode 100644 day24/checker.clj diff --git a/day24/checker.clj b/day24/checker.clj new file mode 100644 index 0000000..4874f62 --- /dev/null +++ b/day24/checker.clj @@ -0,0 +1,47 @@ +(require '[clojure.string :as str]) + +(defn alu-parse-argument [arg] + (if (contains? #{\w \x \y \z} (first arg)) + (str/join ["@" arg]) + (read-string arg))) + +(defn alu-parse-instruction [[ins arg1 arg2]] + (let [arg2-parsed (if (some? arg2) (alu-parse-argument arg2) 0)] + (case ins + "inp" + (str/join ["(reset! " arg1 " (- (int (get input (swap! index inc))) 48))\n"]) + "add" + (str/join ["(swap! " arg1 " +' " arg2-parsed ")\n"]) + "mul" + (str/join ["(swap! " arg1 " *' " arg2-parsed ")\n"]) + "div" + (str/join ["(swap! " arg1 " quot " arg2-parsed ")\n"]) + "mod" + (str/join ["(swap! " arg1 " rem " arg2-parsed ")\n"]) + "eql" + (str/join ["(swap! " arg1 " #(if (= % " arg2-parsed ") 1 0))\n"])))) + +(def alu-program-header + "(defn alu-program [input] + (let [index (atom -1) w (atom 0) x (atom 0) y (atom 0) z (atom 0)]\n") + +(defn alu-compile-program [instructions] + (let [parsed-ins (mapv alu-parse-instruction instructions)] + (eval (read-string + (str/join [alu-program-header + (str/join parsed-ins) + "@z))"]))))) + +(def program (->> (slurp "./in") + str/split-lines + (map #(str/split % #"\s+")) + (alu-compile-program))) + +; to split by `inp w`s: +; (partition 18) +; (reverse) +; (mapv alu-compile-program))) + +(println "Part 1:" (program "16181111641521")) +(println "Part 2:" (program "59692994994998")) + diff --git a/day24/partboth.clj b/day24/partboth.clj index 4874f62..9548ec3 100644 --- a/day24/partboth.clj +++ b/day24/partboth.clj @@ -1,47 +1,41 @@ (require '[clojure.string :as str]) -(defn alu-parse-argument [arg] - (if (contains? #{\w \x \y \z} (first arg)) - (str/join ["@" arg]) - (read-string arg))) - -(defn alu-parse-instruction [[ins arg1 arg2]] - (let [arg2-parsed (if (some? arg2) (alu-parse-argument arg2) 0)] - (case ins - "inp" - (str/join ["(reset! " arg1 " (- (int (get input (swap! index inc))) 48))\n"]) - "add" - (str/join ["(swap! " arg1 " +' " arg2-parsed ")\n"]) - "mul" - (str/join ["(swap! " arg1 " *' " arg2-parsed ")\n"]) - "div" - (str/join ["(swap! " arg1 " quot " arg2-parsed ")\n"]) - "mod" - (str/join ["(swap! " arg1 " rem " arg2-parsed ")\n"]) - "eql" - (str/join ["(swap! " arg1 " #(if (= % " arg2-parsed ") 1 0))\n"])))) - -(def alu-program-header - "(defn alu-program [input] - (let [index (atom -1) w (atom 0) x (atom 0) y (atom 0) z (atom 0)]\n") - -(defn alu-compile-program [instructions] - (let [parsed-ins (mapv alu-parse-instruction instructions)] - (eval (read-string - (str/join [alu-program-header - (str/join parsed-ins) - "@z))"]))))) +; 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+")) - (alu-compile-program))) - -; to split by `inp w`s: -; (partition 18) -; (reverse) -; (mapv alu-compile-program))) - -(println "Part 1:" (program "16181111641521")) -(println "Part 2:" (program "59692994994998")) + (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))))