advent-of-code/2018-12-06.lisp -rw-r--r-- 3.0 KiB View raw
                                                                                
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
(defpackage "AOC/6" (:use "CL"))
(in-package "AOC/6")

(defvar *input* "154, 159
172, 84
235, 204
181, 122
161, 337
305, 104
128, 298
176, 328
146, 71
210, 87
341, 195
50, 96
225, 151
86, 171
239, 68
79, 50
191, 284
200, 122
282, 240
224, 282
327, 74
158, 289
331, 244
154, 327
317, 110
272, 179
173, 175
187, 104
44, 194
202, 332
249, 197
244, 225
52, 127
299, 198
123, 198
349, 75
233, 72
284, 130
119, 150
172, 355
147, 314
58, 335
341, 348
236, 115
185, 270
173, 145
46, 288
214, 127
158, 293
237, 311")

(defun read-coördinates (stream)
  (loop for x = (read stream nil)
        while x
        collect (progn
                  (assert (char= (read-char stream) #\comma))
                  (list x (read stream)))))

;; this is perhaps the hackiest code I’ve written in years — but it
;; gets the correct answer!
(loop for x from 44 to 349
      with grid = (make-array '(350 356) :initial-element nil)
      and coörds = (with-input-from-string (s *input*)
                     (read-coördinates s))
      do (loop for y from 50 to 355
               for dists = (sort (loop for i from 0 and c in coörds
                                       collect (list i (+ (abs (- x (first c)))
                                                          (abs (- y (second c))))))
                                 #'<
                                 :key #'second)
               unless (= (second (first dists)) (second (second dists)))
                 do (progn
                      (setf (aref grid x y)
                            (first (first dists)))))
      finally (progn
                (return (loop with points = (make-hash-table :test 'equal)
                              for x from 44 to 349
                              do (loop for y from 50 to 355
                                       for cell = (aref grid x y)
                                       do (progn
                                            (let ((cell (aref grid x y)))
                                              (when cell
                                                (let ((c (nth cell coörds)))
                                                  (unless (or (= (first c) 1)
                                                              (= (first c) 8)
                                                              (= (second c) 3)
                                                              (= (second c) 9))
                                                    (incf (gethash c points 0))))))))
                              finally (return (loop for k being the hash-keys of points
                                                    maximize (gethash k points)))))))

(loop for x from 0 to 349
      with coörds = (with-input-from-string (s *input*)
                       (read-coördinates s))
      sum (loop for y from 0 to 355
                when (< (loop for c in coörds
                              sum (+ (abs (- x (first c))) (abs (- y (second c)))))
                        10000)
                  count 1))