diff options
Diffstat (limited to 'day18.clj')
-rw-r--r-- | day18.clj | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/day18.clj b/day18.clj new file mode 100644 index 0000000..2b41d98 --- /dev/null +++ b/day18.clj @@ -0,0 +1,70 @@ +(ns org.vuxu.aoc2021.day18 + (:require [clojure.string :as str])) + +(def data + (->> (slurp "day18") + str/split-lines + (map clojure.edn/read-string))) + +(defn add-leftmost [n t] + (if (number? t) + (+ n t) + [(add-leftmost n (first t)) (second t)])) + +(defn add-rightmost [n t] + (if (number? t) + (+ n t) + [(first t) (add-rightmost n (second t))])) + +(defn explode2 [depth t] + (if (number? t) + nil + (let [[l r] t] + (if (= depth 4) + [0 l r] + (if-let [[l' ln rn] (explode2 (inc depth) l)] + [[l' (add-leftmost rn r)] ln 0] + (if-let [[r' ln rn] (explode2 (inc depth) r)] + [[(add-rightmost ln l) r'] 0 rn])))))) + +(defn explode [t] + (first (explode2 0 t))) + +(defn split [t] + (if (number? t) + (if (>= t 10) + [(long (Math/floor (/ t 2))) + (long (Math/ceil (/ t 2)))]) + (let [[l r] t] + (if-let [l' (split l)] + [l' r] + (if-let [r' (split r)] + [l r']))))) + +(defn reduc [t] + (if-let [t' (explode t)] + (recur t') + (if-let [t' (split t)] + (recur t') + t))) + +(defn add [x y] + (reduc (conj [x] y))) + +(defn mag [t] + (if (number? t) + t + (+ (* 3 (mag (first t))) + (* 2 (mag (second t)))))) + +(def part1 + (mag (reduce add data))) +;; => 4173 + +(def part2 + (apply max + (for [x data + y data + :when (not= x y)] + (mag (add x y))))) +;; => 4706 |