-
Notifications
You must be signed in to change notification settings - Fork 1
/
2020-11-seating-system.clj
46 lines (42 loc) · 1.73 KB
/
2020-11-seating-system.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
(defn to-index [width x y]
(+ (* y width) x))
(defn neighbors [board width height distance index]
(for [offv [[1 1] [1 0] [1 -1] [0 1] [0 -1] [-1 1] [-1 0] [-1 -1]]
step (range 1 (inc distance))
:let [[ox oy] offv
sx (mod index width)
sy (int (/ index width))
bx (+ sx (* step ox))
by (+ sy (* step oy))]
:while (and (< -1 bx width) (< -1 by height))
:let [ax (+ sx (* (dec step) ox))
ay (+ sy (* (dec step) oy))
av (board (to-index width ax ay))
bv (board (to-index width bx by))
sv (board index)]
:while (or (= step 1) (= av \.))
:when (and (or (= sv \L) (= sv \#))
(or (= bv \L) (= bv \#)))]
(to-index width bx by)))
(defn step-xf [board threshold]
(comp (map-indexed vector)
(map (fn [[idx adj]]
(let [chr (board idx)
frq (frequencies (map board adj))]
(cond (and (= chr \L) (= (get frq \# 0) 0)) \#
(and (= chr \#) (>= (get frq \# 0) threshold)) \L
:else chr))))))
(defn solve [board seats threshold]
(loop [prev board]
(let [next (into [] (step-xf prev threshold) seats)]
(if (not= prev next)
(recur next)
((frequencies next) \#)))))
(let [input (line-seq (java.io.BufferedReader. *in*))
width (count (first input))
heigt (count input)
board (into [] cat input)
seats (fn [ds] (sequence (map (fn [ix] (neighbors board width heigt ds ix)))
(range (* width heigt))))]
(println "Part A:" (solve board (seats 1) 4))
(println "Part B:" (solve board (seats (max width heigt)) 5)))