|
| 1 | +(ns gear-ratios |
| 2 | + (:require [clojure.string :as str] |
| 3 | + [clojure.set :as set])) |
| 4 | + |
| 5 | +(def vec->long (comp parse-long str/join)) |
| 6 | + |
| 7 | +(defn parse-line [y line] |
| 8 | + (loop [coll line, x 0, parts [], current-part {:yxs #{}, :num []}] |
| 9 | + (if coll |
| 10 | + (if (<= (int \0) (int (first coll)) (int \9)) |
| 11 | + (recur (next coll) |
| 12 | + (inc x) |
| 13 | + parts |
| 14 | + (-> current-part |
| 15 | + (update :num conj (first coll)) |
| 16 | + (update :yxs conj [y x]))) |
| 17 | + (recur (next coll) |
| 18 | + (inc x) |
| 19 | + (if (seq (:yxs current-part)) |
| 20 | + (conj parts (update current-part :num vec->long)) |
| 21 | + parts) |
| 22 | + {:yxs #{}, :num []})) |
| 23 | + (cond-> parts |
| 24 | + (seq (:yxs current-part)) |
| 25 | + (conj (update current-part :num vec->long)))))) |
| 26 | + |
| 27 | +(defn adjacencies [[y x]] |
| 28 | + (for [i [-1 0 1], j [-1 0 1]] |
| 29 | + [(+ y i) (+ x j)])) |
| 30 | + |
| 31 | +;; part 1 |
| 32 | + |
| 33 | +(let [grid |
| 34 | + (->> (slurp "2023/03.in") |
| 35 | + (str/split-lines) |
| 36 | + (mapv vec)) |
| 37 | + |
| 38 | + parts |
| 39 | + (remove (fn [{:keys [yxs]}] |
| 40 | + (= #{\.} |
| 41 | + (set |
| 42 | + (map (fn [yx] (get-in grid yx \.)) |
| 43 | + (set/difference |
| 44 | + (reduce (fn [coll yx] (into coll (adjacencies yx))) #{} yxs) |
| 45 | + yxs))))) |
| 46 | + (into [] (comp (map-indexed parse-line) cat) grid))] |
| 47 | + (reduce + (map :num parts))) |
| 48 | + |
| 49 | +;; part 2 |
| 50 | +(let [grid (->> (slurp "2023/03.in") |
| 51 | + (str/split-lines) |
| 52 | + (mapv vec))] |
| 53 | + (->> grid |
| 54 | + (into [] (comp (map-indexed parse-line) cat)) |
| 55 | + (mapcat (fn [{:keys [yxs num]}] |
| 56 | + (map (fn [yx] [(get-in grid yx \.) yx num]) |
| 57 | + (set/difference |
| 58 | + (reduce (fn [coll yx] (into coll (adjacencies yx))) #{} yxs) |
| 59 | + yxs)))) |
| 60 | + (filter (fn [[s]] (= s \*))) |
| 61 | + (group-by (fn [[a b c]] [a b])) |
| 62 | + (map second) |
| 63 | + (filter #(= 2 (count %))) |
| 64 | + (map #(apply * (map (fn [[_ _ x]] x) %))) |
| 65 | + (reduce +))) |
| 66 | +;; => 81939900 |
0 commit comments