Skip to content

Instantly share code, notes, and snippets.

@JpOnline
Last active December 14, 2023 08:31
Show Gist options
  • Save JpOnline/9182389e2a0823ee6ffbaa0701924fbc to your computer and use it in GitHub Desktop.
Save JpOnline/9182389e2a0823ee6ffbaa0701924fbc to your computer and use it in GitHub Desktop.
Advent of Code 2023 Day 14
;; ---- Day 14 ----
(def input
"O....#....
O.OO#....#
.....##...
OO.#O....O
.O.....O#.
O.#..O.#.#
..O..#O..O
.......O..
#....###..
#OO..#....")
(defn input->board [input]
(mapv vec (clojure.string/split-lines input)))
(defn board->input [board]
(clojure.string/join "\n" (map #(reduce str %) board)))
(defn move-rock [{:keys [is-limit? limit-pos-fn]}]
(fn [board pos]
(let [is-rock? (= \O (get-in board pos))
limit-pos (limit-pos-fn board pos is-limit?)]
(if-not is-rock?
board
(-> board
(assoc-in pos \.)
(assoc-in limit-pos \O))))))
(def move-rock-north
(move-rock
{:is-limit? #(or (< (first %2) 0)
(#{\O \#} (get-in %1 %2)))
:limit-pos-fn #(loop [[y x] %2]
(if (%3 %1 [(dec y) x])
[y x]
(recur [(dec y) x])))}))
(def move-rock-east
(move-rock
{:is-limit? #(or (>= (second %2) (count (first %1)))
(#{\O \#} (get-in %1 %2)))
:limit-pos-fn #(loop [[y x] %2]
(if (%3 %1 [y (inc x)])
[y x]
(recur [y (inc x)])))}))
(def move-rock-south
(move-rock
{:is-limit? #(or (>= (first %2) (count %1))
(#{\O \#} (get-in %1 %2)))
:limit-pos-fn #(loop [[y x] %2]
(if (%3 %1 [(inc y) x])
[y x]
(recur [(inc y) x])))}))
(def move-rock-west
(move-rock
{:is-limit? #(or (< (second %2) 0)
(#{\O \#} (get-in %1 %2)))
:limit-pos-fn #(loop [[y x] %2]
(if (%3 %1 [y (dec x)])
[y x]
(recur [y (dec x)])))}))
(-> input
(input->board)
(move-rock-west [1 2])
(board->input)
(print))
(defn tilt-north [board]
(let [num-rows (count board)
num-colums (count (first board))
all-positions (for [i (range num-rows)
j (range num-colums)]
[i j])]
(reduce move-rock-north board all-positions)))
(def cycle
(memoize
(fn [board]
(let [num-rows (count board)
num-colums (count (first board))
all-positions (for [i (range num-rows)
j (range num-colums)]
[i j])]
(as-> board $
(reduce move-rock-north $ all-positions)
(reduce move-rock-west $ (sort-by second all-positions))
(reduce move-rock-south $ (reverse all-positions))
(reduce move-rock-east $ (reverse (sort-by second all-positions))))))))
(-> input
(input->board)
;; cycle
;; cycle
;; cycle
;; (->> (iterate cycle))
;; (nth 5000)
(process-n 1000000000)
(board->input)
;; (calculate-load)
(print))
(defn calculate-load [input]
(let [board (input->board input)
load-per-row (map-indexed #(* (inc %1) (count (filter #{\O} %2))) (reverse board))]
(reduce + load-per-row)))
(calculate-load (tilt-north (slurp "day-10")))
(-> (slurp "day-10")
(input->board)
(->> (iterate cycle))
(nth 10000000)
(board->input)
(calculate-load))
(defn process-n [board n]
(if (< n 1)
board
(recur (cycle board) (dec n))))
(def day-10-input (slurp "day-10"))
(defn result-of-n [n]
(-> day-10-input
(input->board)
(process-n n)
(board->input)
(calculate-load)))
(filter #(> (count (second %)) 2) (group-by second (map #(into [% (result-of-n %)]) (range 1000))))
(mod (- 1000000000 210) 14)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment