8000 solve: 2023-03 · motform/advent-of-clojure@e391af6 · GitHub
[go: up one dir, main page]

Skip to content

Commit e391af6

Browse files
committed
solve: 2023-03
1 parent 89f0c10 commit e391af6

File tree

2 files changed

+93
-2
lines changed

2 files changed

+93
-2
lines changed

src/advent_of_clojure/2023/03.clj

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
(ns advent-of-clojure.2023.03
2+
(:refer-clojure :exclude [symbol? test])
3+
(:require
4+
[clojure.string :as str]
5+
[clojure.set :as set]
6+
[advent-of-clojure.util.matrix :as grid]))
7+
8+
(def input (->> (-> "resources/2023/03.dat" slurp (str/split-lines))))
9+
10+
(def not-symbol (re-pattern #"[^\d\.]+"))
11+
12+
(defn symbol? [s]
13+
(re-matches not-symbol (str s)))
14+
15+
(defn digit-x [row y index number]
16+
(let [from (str/index-of row number index)
17+
to (+ from (count number))]
18+
(vec (for [x (range from to)] [y x]))))
19+
20+
(defn digits [grid y]
21+
(let [row (get grid y)]
22+
(->> (re-seq #"\d+" row)
23+
(reduce
24+
(fn [{:keys [index] :as state} number]
25+
(let [digit (digit-x row y index number)]
26+
(-> state
27+
(assoc :index (-> digit last last inc))
28+
(update :digits conj digit))))
29+
{:digits [] :index 0})
30+
:digits)))
31+
32+
(defn adjecent-to-digits [bounds digits]
33+
(->> digits
34+
(mapcat (partial grid/diagonal-neighbours bounds))
35+
(remove (set digits))))
36+
37+
(defn adjencent-symbol? [grid bounds points]
38+
(->> points
39+
(adjecent-to-digits bounds)
40+
(some #(symbol? (get-in grid %)))))
41+
42+
(defn get-number [grid points]
43+
(->> points
44+
(map #(get-in grid %))
45+
(apply str)
46+
parse-long))
47+
48+
(defn part-one [grid]
49+
(let [bounds (grid/bounds grid)
50+
digits (mapcat #(digits grid %) (range (count grid)))
51+
xf (comp
52+
(filter #(adjencent-symbol? grid bounds %))
53+
(map #(get-number grid %)))]
54+
(transduce xf + digits)))
55+
56+
(defn asterisks [grid y]
57+
(->> (get grid y)
58+
(map-indexed (fn [x c] (when (= c \*) [y x])))
59+
(remove nil?)))
60+
61+
(defn gear? [grid bounds digits asterisk]
62+
(let [neighbours (set (grid/diagonal-neighbours bounds asterisk))
63+
adjecent-numbers (->> digits
64+
(filter #(seq (set/intersection neighbours (set %))))
65+
(map #(get-number grid %)))]
66+
(when (= 2 (count adjecent-numbers))
67+
adjecent-numbers)))
68+
69+
(defn part-two [grid]
70+
(let [bounds (grid/bounds grid)
71+
rows (range (count grid))
72+
asterisks (mapcat #(asterisks grid %) rows)
73+
digits (mapcat #(digits grid %) rows)
74+
xf (comp
75+
(keep #(gear? grid bounds digits %))
76+
(map #(apply * %)))]
77+
(transduce xf + asterisks)))
78+
79+
(comment
80+
(part-one input)
81+
(part-two input)
82+
)

src/advent_of_clojure/util/matrix.clj

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,24 @@
1616
(and (<= 0 y max-y)
1717
(<= 0 x max-x)))))
1818

19-
(def deltas [[1 0] [-1 0] [0 -1] [0 1]])
2019

21-
(def neighbours
20+
(defn- neighbours' [deltas]
2221
(memoize
2322
(fn [bounds point]
2423
(->> (repeat point)
2524
(mapv v/+ deltas)
2625
(filter (partial in-bounds? bounds))))))
2726

27+
(def deltas [[1 0] [-1 0] [0 -1] [0 1]])
28+
(def neighbours (neighbours' deltas))
29+
30+
(def diagonal-deltas
31+
[[-1 -1] [-1 0] [-1 1]
32+
[0 -1] [0 1]
33+
[1 -1] [1 1] [1 0]])
34+
35+
(def diagonal-neighbours (neighbours' diagonal-deltas))
36+
2837
(defn map-indexed-matrix [f matrix]
2938
(map-indexed
3039
(fn [x row]

0 commit comments

Comments
 (0)
0