/
sol.clj
91 lines (60 loc) · 1.95 KB
/
sol.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
66
67
68
69
70
71
72
73
(ns adv2022.day18.sol
(:require
[clojure.string :as string]
[clojure.set :as set]
[clojure.edn :as edn]
[clojure.math :as math]
[clojure.math.combinatorics :as combo]
[adv2022.grid :as grid]
[adv2022.utils :as util]))
(def input-test (slurp "src/adv2022/day18/input.test"))
(def input-real (slurp "src/adv2022/day18/input.txt"))
(defn parse [input]
(set (map vec (partition 3 (edn/read-string (str "[" input "]"))))))
(def cardinals [[0 1 0]
[0 -1 0]
[1 0 0]
[-1 0 0]
[0 0 1]
[0 0 -1]])
(defn neighbors [p]
(mapv #(mapv + p %) cardinals))
(defn part1 [points]
(->> points
(map #(- 6 (count (filter points (neighbors %)))))
(reduce +)))
#_(= 64 (part1 (parse input-test)))
#_(= 4608 (part1 (parse input-real)))
(defn bfs-flood-filler [bounds points start]
(let [seen (atom #{})]
(loop [q (util/queue start)
accum #{}]
(if-let [curr-point (peek q)]
(if (@seen curr-point)
(recur (pop q) accum)
(do
(swap! seen conj curr-point)
(recur
(into (pop q) (->> (neighbors curr-point)
(remove points)
(filter (partial grid/in-bounds? bounds))))
(conj accum curr-point))))
accum))))
(defn find-outside [points]
(let [bounds (mapv (juxt (comp dec first)
(comp inc second))
(grid/coord-bounds points))
start-point (mapv first bounds)]
(bfs-flood-filler bounds points start-point)))
(defn part2 [points]
(let [points points
outside-set (find-outside points)]
(->> points
(map
(fn [p]
(->> (neighbors p)
(filter #(outside-set %))
count)))
(reduce +))))
#_(= 58 (part2 (parse input-test)))
#_(= 2652 (time (part2 (parse input-real))))