-
Notifications
You must be signed in to change notification settings - Fork 0
/
day21.clj
66 lines (56 loc) · 1.97 KB
/
day21.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
(ns day21
(:require aoc))
(def p2-steps 26501365)
(def sq-size 131)
(def p2-squares (quot p2-steps sq-size))
(defn normalize [[x y]]
(+ (* 1000 (mod y sq-size))
(mod x sq-size)))
(defn calc-total [[a b c]]
(+ a
(* p2-squares
(+ (- b a)
(* (dec p2-squares)
(quot (- (+ c a) b b) 2))))))
(defn traverse [walls start]
(let [p1 (atom 0)
p2 (atom [])
seen-even (atom #{})
seen-odd (atom #{})]
(reduce (fn [current step]
(let [even-step? (zero? (mod step 2))]
(when (= step 64)
(reset! p1 (count @seen-even)))
(when (= 65 (mod step sq-size))
(if even-step?
(swap! p2 conj (count @seen-even))
(swap! p2 conj (count @seen-odd))))
(persistent!
(reduce
(fn [c nbs]
(reduce (fn [c nb]
(if even-step?
(swap! seen-odd conj nb)
(swap! seen-even conj nb))
(conj! c nb))
c
nbs))
(transient #{})
(map (fn [pt] (aoc/neighbours
4 pt
(fn [nb]
(and (not (walls (normalize nb)))
(if even-step?
(not (@seen-odd nb))
(not (@seen-even nb)))))))
current)))))
[start]
(range (+ 1 65 (* 2 sq-size))))
[@p1 (calc-total @p2)]))
(defn solve [input]
(let [input (aoc/parse-input input :chars)
size (count input)
start [(quot size 2) (quot size 2)]
walls (aoc/grid->hashed-point-set input #{\#})]
(traverse walls start)))
(solve (aoc/read-file 21))