~ihabunek/aoc2021

5cf80a762448bd0b668f36ad3a4cce6626009af7 — Ivan Habunek 2 years ago 9fd7af4 day18
Day 18, has a bug
4 files changed, 275 insertions(+), 0 deletions(-)

A resources/day18.example1.in
A resources/day18.example2.in
A resources/day18.in
A src/aoc2021/day18.clj
A resources/day18.example1.in => resources/day18.example1.in +10 -0
@@ 0,0 1,10 @@
[[[0,[4,5]],[0,0]],[[[4,5],[2,6]],[9,5]]]
[7,[[[3,7],[4,3]],[[6,3],[8,8]]]]
[[2,[[0,8],[3,4]]],[[[6,7],1],[7,[1,6]]]]
[[[[2,4],7],[6,[0,5]]],[[[6,8],[2,8]],[[2,1],[4,5]]]]
[7,[5,[[3,8],[1,4]]]]
[[2,[2,2]],[8,[8,1]]]
[2,9]
[1,[[[9,3],9],[[9,0],[0,7]]]]
[[[5,[7,4]],7],1]
[[[[4,2],2],6],[8,7]]
\ No newline at end of file

A resources/day18.example2.in => resources/day18.example2.in +10 -0
@@ 0,0 1,10 @@
[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]]
[[[5,[2,8]],4],[5,[[9,9],0]]]
[6,[[[6,2],[5,6]],[[7,6],[4,7]]]]
[[[6,[0,7]],[0,9]],[4,[9,[9,0]]]]
[[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]]
[[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]]
[[[[5,4],[7,7]],8],[[8,3],8]]
[[9,3],[[9,9],[6,[4,9]]]]
[[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]]
[[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]]
\ No newline at end of file

A resources/day18.in => resources/day18.in +100 -0
@@ 0,0 1,100 @@
[[[[4,0],6],[4,4]],[[6,8],0]]
[[1,[[1,6],0]],[[[8,9],2],[[0,8],[5,5]]]]
[[3,8],7]
[[[8,4],[[4,4],4]],[[3,[0,7]],0]]
[[[[2,0],[4,5]],[7,[2,8]]],5]
[[9,7],[[[8,6],3],[8,[0,2]]]]
[[4,9],[2,[[8,4],2]]]
[9,[[[2,6],[3,2]],[[2,5],[0,0]]]]
[[[9,[8,4]],[7,[1,2]]],[[4,[5,6]],[[5,9],[7,5]]]]
[[[0,[7,5]],[[1,8],1]],[[1,[1,9]],9]]
[[[0,[4,5]],[[1,2],[5,0]]],9]
[[[[7,7],3],1],[[0,[0,7]],[[7,1],[1,9]]]]
[[9,2],[3,[8,[6,1]]]]
[[8,[5,[3,9]]],[1,[3,8]]]
[[1,[[4,4],[4,2]]],4]
[[[5,1],[7,[3,5]]],[[9,[8,4]],9]]
[[5,[0,4]],[[1,[6,5]],9]]
[[[1,0],[4,1]],[[1,[3,2]],2]]
[[[0,[5,9]],[9,[7,2]]],[[4,3],[0,7]]]
[[[[7,9],[0,4]],[[5,6],[0,7]]],[7,[[1,1],[9,5]]]]
[[[[2,6],7],[[8,5],8]],[1,6]]
[[1,[5,5]],[[[3,0],[1,1]],[8,3]]]
[[[[7,4],5],[1,3]],[[6,9],[[3,7],2]]]
[[6,[9,[0,6]]],1]
[8,[4,[2,[2,7]]]]
[[[7,6],[2,8]],[[4,[8,1]],0]]
[4,9]
[[[[6,9],[1,7]],[[4,3],[4,3]]],[[[4,4],[3,6]],[7,[7,0]]]]
[[[7,4],[[9,1],[9,4]]],[6,[[0,4],[4,6]]]]
[[[[3,0],[4,7]],[[8,2],[3,9]]],[4,[0,[5,6]]]]
[[[[1,9],[0,4]],2],[8,[4,[0,9]]]]
[[[[9,6],[3,7]],4],[7,[[0,9],[5,8]]]]
[[5,[[4,0],[0,4]]],[[0,1],[2,[6,0]]]]
[[[2,[9,8]],[[7,9],[6,6]]],[[4,[6,4]],[[2,0],[5,0]]]]
[[[[5,8],8],[[3,1],1]],[[5,7],5]]
[[8,[5,1]],[[[5,5],8],[4,6]]]
[7,[[[3,9],3],[8,6]]]
[[[[8,6],4],8],[[7,[4,0]],[[8,0],4]]]
[[[[7,0],8],[[7,7],1]],[[0,5],[[8,2],5]]]
[4,[3,[3,[6,1]]]]
[[1,[[7,1],[1,2]]],9]
[[[9,[5,7]],[4,[4,7]]],8]
[[[3,[7,2]],[[5,8],6]],[2,0]]
[8,[0,[[7,4],[3,3]]]]
[[[[3,4],[1,1]],3],[[[5,3],0],[[0,7],[6,9]]]]
[3,[[9,1],[3,[0,0]]]]
[[[[8,8],[3,7]],[7,6]],[[[4,7],[9,5]],[5,8]]]
[[[[9,0],[5,6]],[[7,9],5]],0]
[[0,3],[[[9,9],[8,9]],[[7,5],0]]]
[6,[[2,0],3]]
[[[9,3],[[6,9],[8,2]]],[7,[[1,3],[0,5]]]]
[[[[9,5],1],5],[[4,2],[8,[9,5]]]]
[[8,4],[[4,[8,3]],[8,[8,3]]]]
[[[[8,0],[4,4]],[5,2]],[[[0,6],[4,0]],[5,8]]]
[[0,4],[3,[[2,3],7]]]
[[[[6,9],[3,0]],8],[[[4,7],[6,1]],[2,0]]]
[5,[[9,[5,1]],7]]
[[[8,0],[[5,0],0]],[[4,[0,7]],[[6,4],0]]]
[[[1,[0,2]],1],8]
[[[[4,8],[2,0]],[[0,4],9]],[4,[[9,8],[3,8]]]]
[[[1,[6,0]],[6,5]],[3,4]]
[[2,[[4,3],[4,4]]],[[[9,7],8],[5,0]]]
[[[[1,6],2],[[3,5],0]],[[[4,3],[8,1]],[[5,2],[2,1]]]]
[[[[4,8],[1,2]],[9,[3,7]]],[1,[4,4]]]
[[[[2,7],[5,8]],[[2,4],[6,8]]],[9,8]]
[[[1,5],[7,0]],[[8,7],4]]
[[[5,3],[[0,3],[6,2]]],[[8,[7,4]],[5,6]]]
[[[[1,4],1],[8,[2,0]]],[[[0,0],[7,9]],[[1,8],3]]]
[[[[0,0],[4,3]],2],3]
[[[8,[8,9]],[1,[6,1]]],[[6,[5,5]],[5,[9,5]]]]
[[[6,[4,2]],[[1,4],[5,6]]],[0,[[5,9],[2,7]]]]
[3,[[[2,5],2],8]]
[[2,[6,[1,6]]],[0,[4,[9,2]]]]
[[[[7,6],[5,9]],[6,[6,0]]],[2,[3,[1,4]]]]
[[[[1,7],[7,4]],[[6,0],[5,3]]],[2,[[5,2],0]]]
[[[7,[6,1]],[[1,7],[7,2]]],[5,6]]
[[3,2],[6,[9,7]]]
[[[7,[7,5]],[[0,9],5]],[[4,[5,6]],[[8,6],[1,8]]]]
[[[1,[1,6]],7],2]
[[[7,[6,2]],3],[[[5,5],6],9]]
[[[1,[9,8]],[0,5]],[[[2,4],5],[[5,6],7]]]
[[[9,[1,1]],[7,0]],[[5,8],2]]
[[[[8,5],[3,0]],[1,[2,6]]],[[[4,3],[3,2]],0]]
[[[[0,5],7],[7,1]],[4,[[3,4],[9,5]]]]
[[[7,6],[5,1]],[9,3]]
[[[[5,4],6],[2,[0,6]]],[[[6,0],[9,5]],[[8,6],[3,4]]]]
[[0,[6,[9,6]]],[[[1,2],[9,6]],[0,[6,2]]]]
[[[[7,7],6],7],[[8,[0,5]],[0,2]]]
[[[[6,7],[0,7]],[6,[5,0]]],[6,7]]
[[7,[1,8]],[[2,3],[[7,0],3]]]
[[8,[5,7]],[[3,[6,5]],4]]
[[9,9],[[[9,9],9],[2,3]]]
[[[[0,6],[1,4]],5],[1,3]]
[[[9,[8,8]],[[9,9],7]],[2,[[7,1],6]]]
[[[1,8],[1,3]],[[[8,1],8],[[4,2],1]]]
[[4,2],[[[0,7],5],7]]
[[[6,[3,6]],[[0,2],[5,6]]],[[0,1],[[0,9],2]]]
[[[[4,5],[1,4]],1],[[[4,7],[2,3]],6]]
[[[2,2],[0,6]],[[6,[6,4]],1]]
[[[5,[7,7]],[[7,0],1]],2]
\ No newline at end of file

A src/aoc2021/day18.clj => src/aoc2021/day18.clj +155 -0
@@ 0,0 1,155 @@
; --- Day 18: Snailfish ---
; https://adventofcode.com/2021/day/18

(ns aoc2021.day18
  (:require [clojure.java.io :as io]
            [clojure.string :as str]
            [clojure.pprint :refer [pprint]]
            [clojure.edn :as edn]
            [clojure.zip :as zip]))

; (def input-file (-> "day18.example1.in" io/resource io/file))
; (def input-file (-> "day18.example2.in" io/resource io/file))
(def input-file (-> "day18.in" io/resource io/file))

(defn get-input []
  (map (fn [line] (edn/read-string (str/replace line #"," " ")))
    (-> input-file slurp str/split-lines)))

(defn depth
  ([loc] (depth loc 0))
  ([loc depth]
   (if (nil? (zip/up loc))
     depth
     (recur (zip/up loc) (inc depth)))))

(defn explodable? [loc]
  (and (vector? (zip/node loc))
       (= (depth loc) 4)))

(defn splittable? [loc]
  (let [node (zip/node loc)]
    (and (integer? node)
         (>= node 10))))

(defn number? [loc]
  (integer? (zip/node loc)))

(defn add-left [start-loc n]
  (loop [loc start-loc]
    (let [loc (zip/prev loc)]
      (cond
        (nil? loc) start-loc
        (number? loc) (zip/edit loc + n)
        true (recur loc)))))

(defn add-right [start-loc n]
  (loop [loc start-loc]
    (let [loc (zip/next loc)]
      (cond
        (zip/end? loc) start-loc
        (number? loc) (zip/edit loc + n)
        true (recur loc)))))

(defn move-right [loc]
  (let [loc (zip/next loc)]
    (if (number? loc)
      loc
      (move-right loc))))

; if add-left finds a left element, it will increment it by left value and
; return the zipper at that position. if there is no left element, it will
; return the zipper at starting position. in the former case we need to move
; one step right before running add-right. not very elegant.
(defn maybe-move-right [loc prev-loc]
  (if (= loc prev-loc)
    loc
    (move-right loc)))

(defn rewind [loc]
  (zip/vector-zip (zip/root loc)))

(defn explode [loc]
  (println "explode" (zip/node loc))
  (let [[left right] (zip/node loc)
        loc (zip/replace loc 0)]
    (-> loc
        (add-left left)
        (maybe-move-right loc)
        (add-right right))))

(defn split [loc]
  (println "split" (zip/node loc))
  (let [n (zip/node loc)
        l (quot n 2)
        r (+ l (rem n 2))]
    (zip/replace loc [l r])))

(defn step [loc]
  (if (zip/end? loc)
    nil
    (let [loc (zip/next loc)]
      (cond
        (explodable? loc) (rewind (explode loc))
        (splittable? loc) (rewind (split loc))
        true (recur loc)))))

(defn reduce' [numbers]
  (let [loc (zip/vector-zip numbers)]
    (loop [loc loc]
      (println (zip/root loc))
      (let [next (step loc)]
        (if (nil? next)
          (zip/root loc)
          (recur next))))))

(defn add [left right]
  (println "add" [left right])
  (reduce' [left right]))

(defn pair? [node]
  (and (vector? node)
       (= (count node) 2)
       (integer? (first node))
       (integer? (second node))))

(defn pair-value [[a b]]
  (+ (* 3 a) (* 2 b)))

(defn magnitude [numbers]
  (let [loc (zip/vector-zip numbers)]
    (loop [loc loc]
      (if (pair? (zip/root loc))
        (pair-value (zip/root loc))
        (let [node (zip/node loc)
              loc' (if (pair? node)
                     (zip/replace loc (pair-value node))
                     loc)
              loc'' (if (zip/end? loc')
                      (rewind loc')
                      (zip/next loc'))]
            (recur loc''))))))

(defn try' [left right expected]
  (println "  actual" (add left right))
  (println "expected" expected))

(defn main []
  ; (try' [[[[4,0],[5,4]],[[7,7],[6,0]]],[[8,[7,7]],[[7,9],[5,0]]]]
  ;      [[2,[[0,8],[3,4]]],[[[6,7],1],[7,[1,6]]]]
  ;      [[[6,7],[6,7]],[[7,7],[0,7]]],[[[8,7],[7,7]],[[8,8],[8,0]]])

  ; (try' [[[[7,7],[7,8]],[[9,5],[8,7]]],[[[6,8],[0,8]],[[9,9],[9,0]]]]
  ;       [[2,[2,2]],[8,[8,1]]]
  ;       [[[[6,6],[6,6]],[[6,0],[6,7]]],[[[7,7],[8,9]],[8,[8,1]]]]))

  ; (try' [[[[6,6],[6,6]],[[6,0],[6,7]]],[[[7,7],[8,9]],[8,[8,1]]]]
  ;       [2 9]
  ;       [[[[6,6],[7,7]],[[0,7],[7,7]]],[[[5,5],[5,6]],9]]))

  ; (let [numbers (get-input)]
  ;   (println "\nactual:  " (reduce add (take 2 numbers)))
  ;   (println "expected: [[[[4 0] [5 4]] [[7 7] [6 0]]] [[8 [7 7]] [[7 9] [5 0]]]]")))

  (let [numbers (get-input)]
    (println (magnitude (reduce add numbers)))))