Created
December 3, 2023 17:53
-
-
Save Alwinfy/f802ec08ae097fe1f627c062dfee1946 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(set! *warn-on-reflection* true) | |
(def data | |
(with-open [rdr (clojure.java.io/reader "day03.in")] | |
(reduce conj [] (line-seq rdr)))) | |
(defn access [data [x y]] | |
(when (< -1 x (count data)) | |
(let [row (nth data x)] | |
(when (< -1 y (count row)) | |
(let [ch ^char (nth row y)] | |
(if (Character/isDigit ch) | |
(Character/digit ch 10) | |
(when (not= ch \.) ch))))))) | |
(defn indices [data] | |
(for [x (range (count data)) | |
y (range (count (nth data x)))] | |
[x y])) | |
(defn neighbors [[x y]] | |
(for [i [-1 0 1] | |
j [-1 0 1] | |
:when (not (and (zero? i) (zero? j)))] | |
[(+ i x) (+ j y)])) | |
(defn nearbys [[x y]] | |
[[x (inc y)] [x (dec y)]]) | |
(defn scan [start transition] | |
(loop [queue (seq start) | |
seen #{} | |
pings {}] | |
(if-let [[h & t] queue] | |
(if (seen h) | |
(recur t seen pings) | |
(let [[out nbrs] (transition h)] | |
(recur (reduce conj t nbrs) | |
(conj seen h) | |
(if (seq out) | |
(apply update-in pings out) | |
pings)))) | |
pings))) | |
(defn start [data] | |
(for [pos (filter #(char? (access data %)) (indices data)) | |
nbr (neighbors pos)] | |
[pos nbr])) | |
(defn transition [data] | |
(fn [[start pos]] | |
(if (int? (access data pos)) | |
[[pos (constantly start)] | |
(map #(conj [start] %) (nearbys pos))] | |
[nil nil]))) | |
(defn parse-numbers [data raw] | |
(mapcat | |
(fn [raw row] | |
(when raw | |
(mapcat | |
(fn [indices] | |
(when-let [src (raw (first indices))] | |
[[src (Integer/parseInt (apply str (map (partial nth row) indices)))]])) | |
(partition-by raw (range (count row)))))) | |
(map raw (range)) | |
data)) | |
(def numbers (parse-numbers data (scan (start data) (transition data)))) | |
(prn (reduce + (map second numbers))) | |
(def nummap (reduce (fn [m [k v]] (update m k #(conj % v))) {} numbers)) | |
(prn (reduce + | |
(map | |
(fn [[k v]] | |
(if (and (= (access data k) \*) | |
(= (count v) 2)) | |
(apply * v) | |
0)) | |
nummap))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment