-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday09.clj
70 lines (58 loc) · 1.52 KB
/
day09.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
(ns day09
(:require aoc
[clojure.data.int-map :refer [dense-int-set]]
[clojure.math :as math]
[clojure.string :as str]))
(def ^:const N 500)
(def ^:const start (* (inc N) (/ N 2)))
(defn parse-motion [line]
(->> (str/split line #" ")
((fn [[dir amount]]
(repeat (parse-long amount) (keyword dir))))))
(defn move-head [^long pt cmd]
(case cmd
:U (- pt N)
:D (+ pt N)
:L (dec pt)
:R (inc pt)))
(defn follow ^long [^long head ^long tail]
(let [hx (rem head N)
hy (quot head N)
tx (rem tail N)
ty (quot tail N)
dx (- hx tx)
dy (- hy ty)]
(if (< (max (abs dx) (abs dy)) 2)
tail
(+ tail (long (math/signum dx)) (* N (long (math/signum dy)))))))
(defn move-tail [head tail]
(reduce
(fn [rope tail-piece]
(->> tail-piece
(follow (peek rope))
(conj rope)))
[head]
tail))
(defn move-rope [[head & tail] cmd]
(-> head
(move-head cmd)
(move-tail tail)))
(defn simulate [motions]
(reduce
(fn [[rope seen-2 seen-10] cmd]
(let [new-pos (move-rope rope cmd)]
[new-pos
(conj! seen-2 (nth new-pos 1))
(conj! seen-10 (nth new-pos 9))]))
[(vec (repeat 10 start))
(transient (dense-int-set))
(transient (dense-int-set))]
motions))
(defn solve
([] (solve (aoc/read-file 9)))
([input]
(let [motions (mapcat parse-motion (aoc/parse-input input))
[_ p1 p2] (simulate motions)]
[(count p1)
(count p2)])))
(solve)