Skip to content

Commit

Permalink
Add 2023 day 22
Browse files Browse the repository at this point in the history
  • Loading branch information
WillFlame14 committed Dec 22, 2023
1 parent 1ba4804 commit beb7ddd
Showing 1 changed file with 80 additions and 0 deletions.
80 changes: 80 additions & 0 deletions 2023/day22.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
(ns clojure-aoc.core (:gen-class)
(:require [clojure-aoc.grids :as grids]
clojure.set
clojure.string))

(def input (-> (slurp "input.txt") (clojure.string/split #"\n")))

(defn parse-brick [line]
(let [[x1 y1 z1 x2 y2 z2] (->> (re-matches #"(\d+),(\d+),(\d+)~(\d+),(\d+),(\d+)" line) next (map #(Integer/parseInt %)))]
[(gensym) [[x1 x2] [y1 y2] [z1 z2]]]))

(defn fall-brick [fallen [id [[x1 x2] [y1 y2] [z1 z2]]]]
(let [xy-coords (for [x (range x1 (inc x2)) y (range y1 (inc y2))] [x y])
final-z (->> xy-coords (map #(->> (grids/at fallen %) keys (apply max))) (apply max) inc)
new-fallen (if (= z1 z2)
(reduce (fn [acc [x y]] (assoc-in acc [y x final-z] id)) fallen xy-coords)
(reduce (fn [acc z] (assoc-in acc [y1 x1 z] id)) fallen (range final-z (+ final-z (Math/abs (- z2 z1)) 1))))
new-coords [[x1 x2] [y1 y2] [final-z (+ final-z (Math/abs (- z2 z1)))]]]
[new-fallen [id new-coords]]))

(defn find-supporting [fallen [[x1 x2] [y1 y2] [z1 z2]]]
(let [xy-coords (for [x (range x1 (inc x2)) y (range y1 (inc y2))] [y x (inc (max z1 z2))])]
(->> xy-coords
(map #(get-in fallen %))
(filter (complement nil?))
distinct)))

(defn find-supported [fallen [[x1 x2] [y1 y2] [z1 z2]]]
(let [xy-coords (for [x (range x1 (inc x2)) y (range y1 (inc y2))] [x y])]
(->> xy-coords
(map (fn [[x y]] (get-in fallen [y x (dec (min z1 z2))])))
(filter (complement nil?))
distinct)))

(defn multi-support? [fallen bricks id]
(let [supporting (find-supported fallen (bricks id))]
(> (count supporting) 1)))

(defn safe-disintegrate [fallen bricks [_ coords]]
(let [supported-bricks (find-supporting fallen coords)]
(every? #(multi-support? fallen bricks %) supported-bricks)))

(def part1
(let [bricks (->> (map parse-brick input) (sort-by (fn [[_ [_ _ [z1 z2]]]] (min z1 z2))))
ground (vec (repeat 10 (vec (repeat 10 {0 :ground}))))
reducer (fn [[fallen final-bricks] brick]
(let [[new-fallen new-brick] (fall-brick fallen brick)]
[new-fallen (conj final-bricks new-brick)]))
[final-fallen final-bricks] (reduce reducer [ground {}] bricks)]
(->> final-bricks
(filter #(safe-disintegrate final-fallen final-bricks %))
count)))

(defn get-supported [fallen bricks]
(reduce (fn [acc [id coords]] (assoc acc id (find-supported fallen coords))) {} bricks))

(defn disintegrate-fall [bricks supported-by id]
(loop [disintegrated #{id}]
(let [new-disintegrated (->> (map first bricks)
(filter (fn [id] (and (not (contains? disintegrated id))
(every? #(contains? disintegrated %) (supported-by id))))))]
(if (empty? new-disintegrated)
disintegrated
(recur (into disintegrated new-disintegrated))))))

(def part2
(let [bricks (->> (map parse-brick input) (sort-by (fn [[_ [_ _ [z1 z2]]]] (min z1 z2))))
ground (vec (repeat 10 (vec (repeat 10 {0 :ground}))))
reducer (fn [[fallen final-bricks] brick]
(let [[new-fallen new-brick] (fall-brick fallen brick)]
[new-fallen (conj final-bricks new-brick)]))
[final-fallen final-bricks] (reduce reducer [ground {}] bricks)
supported-by (get-supported final-fallen final-bricks)]
(->> final-bricks
(map #(disintegrate-fall final-bricks supported-by (first %)))
(map (comp dec count))
(apply +))))

(defn -main [& args]
(println (str part1 " " part2)))

0 comments on commit beb7ddd

Please sign in to comment.