/
day20.clj
80 lines (68 loc) · 2.77 KB
/
day20.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
74
75
76
77
78
79
80
(ns adventofcode.day20
(:require [clojure.string :as str]
[clojure.java.io :as io]))
(set! *warn-on-reflection* true)
(set! *unchecked-math* :warn-on-boxed)
;; p=<-11104,1791,5208>, v=<-6,36,-84>, a=<19,-5,-4>
(def input (->> "day20/input" io/resource slurp))
(def parsed-input (re-seq #"p=<([-0-9]*),([-0-9]*),([-0-9]*)>, v=<([-0-9]*),([-0-9]*),([-0-9]*)>, a=<([-0-9]*),([-0-9]*),([-0-9]*)>" input))
(defn abs ^long [^long v]
(if (pos? v)
v
(- v)))
(defn solve-1 []
(ffirst (sort-by
(juxt #(nth % 3) #(nth % 2) #(nth % 1))
(map-indexed
(fn [i [line x y z vx vy vz ax ay az]]
[i
(+ (abs (read-string x))
(abs (read-string y))
(abs (read-string z)))
(+ (abs (read-string vx))
(abs (read-string vy))
(abs (read-string vz)))
(+ (abs (read-string ax))
(abs (read-string ay))
(abs (read-string az)))
line])
parsed-input))))
(def particle {:id 0
:position [0 0 0]
:velocity [0 0 0]
:acceleration [0 0 0]})
(def particles (map-indexed
(fn [i [line x y z vx vy vz ax ay az]]
{:id i
:position [(read-string x) (read-string y) (read-string z)]
:velocity [(read-string vx) (read-string vy) (read-string vz)]
:acceleration [(read-string ax) (read-string ay) (read-string az)]})
parsed-input))
(defn remove-collisions [particles]
(as-> particles $
(group-by :position $)
(remove (fn [[_ particles]] (< 1 (count particles))) $)
(mapcat val $)))
(defn step [particle]
(let [velocity (mapv + (:velocity particle) (:acceleration particle))
position (mapv + (:position particle) velocity)]
(-> particle
(assoc :velocity velocity)
(assoc :position position))))
(defn abs-distance [xyz]
(reduce + (map abs xyz)))
(defn solve-2 []
(let [particle-steps (iterate (fn [particles]
(sort-by (juxt #(abs-distance (:acceleration %))
#(abs-distance (:velocity %))
#(abs-distance (:position %)))
(remove-collisions
(map step particles))))
particles)]
(count (reduce (fn [r v]
(let [ids (map :id v)]
(if (= r ids) (reduced ids) ids)))
[] particle-steps))))
(defn -main [& args]
(println "part1:" (time (solve-1)))
(println "part2:" (time (solve-2))))