-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday03.clj
65 lines (53 loc) · 1.87 KB
/
day03.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
(ns day03
(:require aoc
[clojure.string :as str]))
(def digits (set (str/join (range 10))))
(defn symbol-coords [grid]
(set (keys (remove #(digits (val %)) grid))))
(defn gear-ratios [gear-values]
(keep
#(when (= 2 (count %))
(reduce * %))
gear-values))
(defn touching [symbs x y len]
(for [yy (range (dec y) (+ y 2))
xx (range (dec x) (inc (+ x len)))
:let [pt [xx yy]]
:when (symbs pt)]
pt))
(defn find-solution [lines symbs gears]
(loop [lines lines
y 0
acc 0
gear-map {}]
(if-let [line (first lines)]
(let [[acc' gear-map' _]
(reduce
(fn [[acc'' gear-map'' start] n]
(let [x (str/index-of line n start)
number (parse-long n)
len (count n)
nearby-gears (touching gears x y len)
near-symbs? (or (seq nearby-gears)
(seq (touching symbs x y len)))]
[(if near-symbs? (+ acc'' number) acc'')
(if (seq nearby-gears)
(reduce (fn [gmap gear]
(update gmap gear conj number))
gear-map''
nearby-gears)
gear-map'')
(+ x len)]))
[acc gear-map 0]
(re-seq #"\d+" line))]
(recur (rest lines) (inc y) acc' gear-map'))
{:num-sum acc
:gear-ratios (reduce + (gear-ratios (vals gear-map)))})))
(defn solve [input]
(let [lines (aoc/parse-input input)
points (aoc/grid->point-map lines #(not= % \.))
symbs (symbol-coords points)
gears (set (filter #(= \* (points %)) symbs))
solution (find-solution lines symbs gears)]
((juxt :num-sum :gear-ratios) solution)))
(solve (aoc/read-file 3))