Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (def rocks (cycle
- [[[1 1] [1 2] [1 3] [1 4]]
- [[2 1] [1 2] [2 2] [3 2] [2 3]]
- [[1 1] [1 2] [1 3] [2 3] [3 3]]
- [[1 1] [2 1] [3 1] [4 1]]
- [[1 1] [1 2] [2 2] [2 1]]]))
- (defn build-state [grid]
- (for [potential (range 1 8)]
- (as-> (iterate dec (:h grid)) y
- (filter #(or (some? (get-in grid [% potential] nil)) (zero? %)) y)
- (first y)
- [(- y (:h grid)) potential])))
- (defn place-rock [grid coords]
- (as-> grid g
- (reduce (fn [res [y x :as coord]] (-> res (assoc-in coord true) (update-in [:h] max y))) g coords)))
- (defn move [grid rock dir]
- (let [transforms (repeat (count rock) (case dir "d" [dec identity] "<" [identity dec] ">" [identity inc]))
- coords (vec (map (fn [[y x] [yt xt]] [(yt y) (xt x)]) rock transforms))]
- (cond
- (and
- (every? pos? (flatten coords))
- (every? #(< % 8) (map second coords))
- (not-any? true? (map #(get-in grid %) coords)))
- [grid coords]
- (not= "d" dir)
- [grid rock]
- :else
- [(place-rock grid rock) nil])))
- (defn gen-rock [highest rock]
- (vec (map (fn [[y x]] [(+ highest 3 y) (+ 2 x)]) rock)))
- (defn simulate [blasts stop & [rock blast state]]
- (loop
- [grid (merge {:h (apply max 0 (keys state)) :state {}} state)
- rocks (nthrest rocks (or rock 0))
- rock (gen-rock (:h grid) (first rocks))
- fallen 0
- dirs (nthrest (interpose "d" (cycle blasts)) (or blast 0))
- iterations (or blast 0)]
- (let [[grid rock] (move grid rock (first dirs))]
- (cond
- (= fallen stop) [(:h grid) nil]
- (some? rock) (recur grid rocks rock fallen (rest dirs) (inc iterations))
- :else (let [state (build-state grid)]
- (if (zero? (mod (- iterations (get-in grid [:state state 2] (- iterations 1))) (count blasts)))
- [state iterations [(:h grid) (inc fallen)] ((:state grid) state)]
- (recur
- (update-in grid [:state] assoc state [(:h grid) (inc fallen) iterations])
- (rest rocks)
- (gen-rock (:h grid) (second rocks))
- (inc fallen)
- (rest dirs)
- (inc iterations))))))))
- (defn build-wall [blasts stop]
- (as-> (simulate blasts stop) data
- (if (nil? (second data)) data
- (let [[state blast [last-highest last-fallen] [old-highest old-fallen _]] data]
- (def iterable-stop (- stop last-fallen))
- (def iterations (quot iterable-stop (- last-fallen old-fallen)))
- (def new-highest (+ last-highest (* iterations (- last-highest old-highest))))
- (def new-fallen (+ last-fallen (* iterations (- last-fallen old-fallen))))
- (def lowest (apply min (map first state)))
- (def new-grid (reduce (fn [res [y x]] (assoc-in res [(- y lowest) x] true)) {} state))
- (def remaining (simulate blasts (- stop new-fallen) (mod new-fallen 5) (inc blast) new-grid))
- (+ new-highest (first remaining) lowest)))))
- (def data
- (-> (slurp "rocks.test")
- (clojure.string/replace "\n" "")
- (clojure.string/split #"")))
- (println (build-wall data 2022))
- (println (build-wall data 1000000000000))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement