Created
December 18, 2021 06:33
-
-
Save erdos/797f5a63016b919e43d619fb3a957b49 to your computer and use it in GitHub Desktop.
Advent Of Code 2021 Day 18 in Clojure with zippers
This file contains hidden or 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
(require '[clojure.zip :as zip]) | |
(def input (slurp "day18.txt")) | |
(def lines (vec (s/split-lines input))) | |
(def vecs (map read-string lines)) | |
(defn magnitude [x] | |
(if (number? x) | |
x | |
(+ (* 3 (magnitude (first x))) (* 2 (magnitude (second x)))))) | |
(defn split-regular [x] (assert (integer? x)) | |
[(int (/ x 2)) (int (Math/ceil (/ x 2)))]) | |
(defn depth [z] (if (nil? z) -1 (inc (depth (zip/up z))))) | |
(defn next-leaf [z] | |
(when z | |
(if-let [zr (zip/right z)] | |
(loop [zd zr] | |
(if (number? (zip/node zd)) | |
zd | |
(recur (zip/down zd)))) | |
(recur (zip/up z))))) | |
(defn prev-leaf [z] | |
(when z | |
(if-let [zr (zip/left z)] | |
(loop [zd zr] | |
(if (number? (zip/node zd)) | |
zd | |
(recur (zip/rightmost (zip/down zd))))) | |
(recur (zip/up z))))) | |
(defn explode-4-deep [x] | |
(loop [zipper (zip/vector-zip x)] | |
(when-not (zip/end? zipper) | |
; (println :! (zip/node zipper)) | |
(let [depth (depth zipper)] | |
(if (and (= 4 depth) (vector? (zip/node zipper))) | |
(let [[left right] (zip/node zipper)] | |
(-> (zip/replace zipper 0) | |
((fn [zipper] | |
(if-let [pz (prev-leaf zipper)] | |
(next-leaf (zip/edit pz + left)) ;; return to zero | |
zipper))) | |
((fn [zipper] | |
(if-let [nz (next-leaf zipper)] | |
(zip/edit nz + right) | |
zipper))) | |
(zip/root))) | |
(recur (zip/next zipper))))))) | |
(defn split-leftmost-10 [x] | |
(if (vector? x) | |
(if-let [ls (split-leftmost-10 (first x))] | |
[ls (second x)] | |
(if-let [rs (split-leftmost-10 (second x))] | |
[(first x) rs])) | |
(when (>= x 10) (split-regular x)))) | |
(defn reduced-result [x] | |
(let [fx (or (explode-4-deep x) | |
(split-leftmost-10 x) | |
x)] | |
(if (= x fx) fx | |
(recur fx)))) | |
(defn addition [a b] (reduced-result [a b])) | |
(println :first-answer (magnitude (reduce addition vecs))) | |
(println :second-answer | |
(apply max (for [a vecs b vecs :when (not= a b)] | |
(magnitude (addition a b))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment