-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path20.lisp
40 lines (37 loc) · 1.47 KB
/
20.lisp
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
(in-package #:cl-user)
(defun load-points (input)
(with-open-file (s input :direction :input)
(loop for line = (read-line s nil)
while line collecting (destructuring-bind (drop1 p drop2 v drop3 a)
(read-from-string (format nil "(~A)"
(nsubstitute #\Space #\= (nsubstitute #\) #\> (nsubstitute #\( #\< (nsubstitute #\Space #\, line))))))
(list p v a)))))
(defun part1 (input)
(let ((particles (load-points input)))
(loop for particle in particles
for pos from 0
for acc = (third particle) for mag = (loop for c in acc summing (expt c 2))
with minpos and min = most-positive-fixnum when (> min mag) do
(setf minpos pos
min (min min mag))
finally (return minpos))))
(defun part2 (input &optional (iterations 1000))
(let ((particles (load-points input)))
(flet ((incvec (to with)
(loop for pos from 0 to 2 do
(incf (nth pos to) (nth pos with)))))
(loop repeat iterations do
(loop for particle in particles
for position = (first particle)
for velocity = (second particle)
for acceleration = (third particle) do
(incvec velocity acceleration)
(incvec position velocity))
(let ((matches '()))
(setf particles (remove-if #'(lambda (x)
(member x matches :test #'equalp))
(remove-duplicates particles :test #'(lambda (a b)
(when (equalp (first a) (first b))
(push (first a) matches))))
:key #'first))))
(length particles))))