Guest User

Day 9 2021

a guest
Dec 9th, 2021
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (def cave (->> "/home/bobini/Pulpit/cave.txt"
  2.                    slurp
  3.                    clojure.string/trim
  4.                    clojure.string/split-lines
  5.                    (map clojure.string/trim)
  6.                    (map (fn [line] (map #(Character/digit % 10) line)))
  7.                    (map vec)
  8.                    vec))
  9.  
  10. (defn adjacent-coords [y x y-max x-max]
  11.   (cond-> []
  12.     (> x 0) (conj [y (dec x)])
  13.     (> y 0) (conj [(dec y) x])
  14.     (< y y-max) (conj [(inc y) x])
  15.     (< x x-max) (conj [y (inc x)])))
  16.  
  17. (defn any-adjacent-lower? [cave y x y-max x-max]
  18.   (some #(<= % (get-in cave [y x]))
  19.         (map #(get-in cave %)
  20.              (adjacent-coords y x y-max x-max))))
  21.  
  22. (defn get-low-points [cave]
  23.   (let [y-max (dec (count cave))
  24.         x-max (dec (count (first cave)))]
  25.     (reduce #(if (not (any-adjacent-lower? cave (first %2) (second %2) y-max x-max))
  26.                (conj %1 %2)
  27.                %1)
  28.             []
  29.             (for [y (range (inc y-max))
  30.                   x (range (inc x-max))]
  31.               [y x]))))
  32.  
  33. (defn find-first-unfilled [cave coords]
  34.   (first (filter #(not= 9 (get-in cave %)) coords)))
  35.  
  36. (defn fill-one-basin [cave start]
  37.   (let [y-max (dec (count cave))
  38.         x-max (dec (count (first cave)))]
  39.   (loop [cave cave
  40.          size 0
  41.          queue #{start}]
  42.     (if (empty? queue)
  43.       [cave size]
  44.       (let [current (first queue)]
  45.         (if (= 9 (get-in cave current))
  46.           (recur cave size (disj queue current))
  47.           (recur (assoc-in cave current 9)
  48.                  (inc size)
  49.                  (-> queue
  50.                      (disj current)
  51.                      (into (adjacent-coords
  52.                             (first current) (second current)
  53.                             y-max x-max))))))))))
  54.  
  55.  
  56. (defn count-basin-sizes [cave]
  57.   (let [y-max (dec (count cave))
  58.         x-max (dec (count (first cave)))
  59.         coords (for [y (range (inc y-max))
  60.                      x (range (inc x-max))]
  61.                  [y x])]
  62.     (loop [cave cave
  63.            sizes []]
  64.       (if-let [start (find-first-unfilled cave coords)]
  65.         (let [[new-cave size] (fill-one-basin cave start)]
  66.           (recur new-cave (conj sizes size)))
  67.         sizes))))
  68.  
  69. (def answer9-2 (apply * (->> cave
  70.                              count-basin-sizes
  71.                              sort
  72.                              reverse
  73.                              (take 3))))
Advertisement
Add Comment
Please, Sign In to add comment