Skip to content

Instantly share code, notes, and snippets.

@armstnp
Last active December 18, 2021 18:06
Show Gist options
  • Save armstnp/c7e95ec222699bde529f3642b4740852 to your computer and use it in GitHub Desktop.
Save armstnp/c7e95ec222699bde529f3642b4740852 to your computer and use it in GitHub Desktop.
Wisply Clojure Test 2
ns advent-of-code-2021.day18
:require :[ advent-of-code-2021.core :as core
. :[ clojure.string :as str
. :[ clojure.zip :as z
def input
->> "day18.txt"
. core/read-input
. str/split-lines
. map read-string
;; Part 1 Solution
defn bump
"Iterate x, (f x), (f (f x)) until one of the results is nil, at which point
the last non-nil result is returned. If x is nil, nil is returned."
[f x]
when x
if-let :[ fx : f x
recur f fx
x
defn next-leaf
"Find the next leaf node in a standard in-order tree traversal."
[zipper]
loop [zipper zipper]
let :[ zipper' : z/next zipper
cond
(z/end? zipper') nil
(int? (z/node zipper')) zipper'
:else : recur zipper'
defn prev-leaf
"Find the previous leaf node in a standard in-order tree traversal."
[zipper]
loop [zipper zipper]
when-let :[ zipper' : z/prev zipper
if : int? (z/node zipper')
zipper'
recur zipper'
defn explode [zipper]
let
:[
[l r] : z/node zipper
zipper' : z/replace zipper 0
zipper'
if-let :[ zl : prev-leaf zipper'
next-leaf : z/edit zl + l
zipper'
zipper'
if-let :[ zr : next-leaf zipper'
prev-leaf : z/edit zr + r
zipper'
zipper'
defn split-fish [zipper]
z/edit
zipper
# let :[ half {- % / 2 -}
mapv int [(Math/floor half) (Math/ceil half)]
defn find-node [pred zipper]
cond
(z/end? zipper) nil
(pred zipper) zipper
:else : recur pred (z/next zipper)
defn find-exploder [zipper]
find-node
# and {- 4 = (count (z/path %)) -}
vector? : z/node %
zipper
defn find-splitter [zipper]
find-node
# and int? : z/node %
{- (z/node %) >= 10 -}
zipper
defn reduce-fish [zipper]
if-let :[ exploder : find-exploder zipper
recur : bump z/up (explode exploder)
if-let :[ splitter : find-splitter zipper
recur : bump z/up (split-fish splitter)
z/root zipper
defn add-fish [fish-a fish-b]
reduce-fish : z/vector-zip [fish-a fish-b]
defn magnitude [x]
if : int? x
x
let :[ [l r] x
{- (3 * (magnitude l)) + (2 * (magnitude r)) -}
->> input
. reduce add-fish
. magnitude
;; Part 2 Solution
apply max
for
:[
x input
y input
:when : not= x y
magnitude : add-fish x y
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment