]> code.bitgloo.com Git - clyne/advent-of-code.git/commitdiff
day24: solve using code
authorClyne Sullivan <clyne@bitgloo.com>
Sun, 26 Dec 2021 13:41:42 +0000 (08:41 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Sun, 26 Dec 2021 13:41:42 +0000 (08:41 -0500)
day24/checker.clj [new file with mode: 0644]
day24/partboth.clj

diff --git a/day24/checker.clj b/day24/checker.clj
new file mode 100644 (file)
index 0000000..4874f62
--- /dev/null
@@ -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"))
+
index 4874f62e849a69821eed27a7f2f7e1a101eaf09e..9548ec30b2c122046c0200819103281fdbd026fc 100644 (file)
@@ -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))))