about summary refs log tree commit diff
path: root/day14.clj
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2020-12-15 20:23:31 +0100
committerLeah Neukirchen <leah@vuxu.org>2020-12-15 20:23:31 +0100
commit76933fddfe8deb9d18c40ea974bbe71bbc7dd319 (patch)
tree6377b66a2068d358ba1ea4d36a58a46893ea9393 /day14.clj
parentd58d88e5c3563e50897a3c7b1cbd16b6e3ed38c9 (diff)
downloadadventofcode2020-76933fddfe8deb9d18c40ea974bbe71bbc7dd319.tar.gz
adventofcode2020-76933fddfe8deb9d18c40ea974bbe71bbc7dd319.tar.xz
adventofcode2020-76933fddfe8deb9d18c40ea974bbe71bbc7dd319.zip
day14
Diffstat (limited to 'day14.clj')
-rw-r--r--day14.clj48
1 files changed, 48 insertions, 0 deletions
diff --git a/day14.clj b/day14.clj
new file mode 100644
index 0000000..a10be8d
--- /dev/null
+++ b/day14.clj
@@ -0,0 +1,48 @@
+(def data
+  (->> (slurp "day14")
+       (clojure.string/split-lines)))
+
+(defn part1 [mem mask code]
+  (if (seq code)
+    (if-let [[_ new-mask] (re-matches #"mask = (.*)" (first code))]
+      (recur mem
+             [(Long/parseLong (apply str (replace {\X \0} new-mask)) 2)
+              (Long/parseLong (apply str (replace {\1 \0, \0 \1, \X 0} new-mask)) 2)]
+             (rest code))
+      (if-let [[_ addr value] (re-matches #"mem\[(\d+)\] = (\d+)" (first code))]
+        (recur (assoc mem
+                      (Integer/parseInt addr)
+                      (bit-and (bit-or (Integer/parseInt value) (first mask))
+                               (bit-not (second mask))))
+               mask
+               (rest code))))
+    mem))
+
+(apply + (vals (part1 {} [0 0] data))) ; => 7997531787333
+
+(defn part2-mem [mask prefix n m]
+  (if (seq mask)
+    (case (first mask)
+      \0 (part2-mem (rest mask)
+                    (+ (if (bit-test m (dec (count mask))) 1 0)
+                       (* 2 prefix))
+                    n m)
+      \1 (part2-mem (rest mask) (inc (* 2 prefix)) n m)
+      \X (concat (part2-mem (rest mask) (* 2 prefix) n m)
+                 (part2-mem (rest mask) (inc (* 2 prefix)) n m)))
+    [[prefix n]]))
+
+(defn part2 [mem mask code]
+  (if (seq code)
+    (if-let [[_ new-mask] (re-matches #"mask = (.*)" (first code))]
+      (recur mem new-mask (rest code))
+      (if-let [[_ addr value] (re-matches #"mem\[(\d+)\] = (\d+)" (first code))]
+        (recur (into mem
+                     (part2-mem mask 0
+                                (Integer/parseInt value)
+                                (Integer/parseInt addr)))
+               mask
+               (rest code))))
+    mem))
+
+(apply + (vals (part2 {} [0 0] data))) ; => 3564822193820