blob: 08fb4509e1d923553d9308f5dfaf7ce64d44c718 (
plain)
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
|
;; 13:45
(ql:quickload '(fiveam arrows str))
(defun roll-to-west (line)
(arrows:->>
(str:split "#" line)
(mapcar (lambda (ranges) (sort ranges #'char>)))
(str:join "#")))
(defun transpose-rows (rows)
(apply #'map 'list (lambda (&rest vals)
(concatenate 'string vals)) rows))
(defun north-load (field)
(loop
for row in field
for weight from (length field) downto 0
sum (* weight (count #\O row))))
(defun solve1 (input)
(arrows:->>
input
(transpose-rows)
(mapcar #'roll-to-west)
(transpose-rows)
(north-load)))
(defun cycle (field)
(loop repeat 4
do (arrows:->>
field
(transpose-rows)
(mapcar #'roll-to-west)
(mapcar #'nreverse)
(setf field)))
field)
(defun value-hash (hash-table value)
(maphash (lambda (k v)
(when (equal v value)
(return-from value-hash k)))
hash-table))
(defun solve2 (input max-cycles)
(let ((seen (make-hash-table :test #'equal))
first-in-series)
(loop repeat max-cycles
for i from 0
for field = input then (cycle field)
for strf = (str:join #\Newline field)
until (gethash strf seen)
do (setf (gethash strf seen) i)
finally (setf first-in-series strf))
(let* ((last (hash-table-count seen))
(first (gethash first-in-series seen))
(sp (+ first (rem (- max-cycles first) (- last first))))
(ss (value-hash seen sp)))
;; (list last first seen
;; (rem (- max-cycles first) (- last first))
;; ss
;; sp)
(north-load (str:split #\Newline ss)))))
(fiveam:test solutions
(fiveam:is (= 136 (solve1 (uiop:read-file-lines "eg-in"))))
(fiveam:is (= 108935 (solve1 (uiop:read-file-lines "input"))))
(fiveam:is (= 64 (solve2 (uiop:read-file-lines "eg-in") 1000000000)))
(fiveam:is (= 100876(solve2 (uiop:read-file-lines "input") 1000000000))))
(time
(fiveam:run!))
|