-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathday20.lisp
More file actions
38 lines (31 loc) · 1.33 KB
/
day20.lisp
File metadata and controls
38 lines (31 loc) · 1.33 KB
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
(defpackage :aoc/2016/20 #.cl-user::*aoc-use*)
(in-package :aoc/2016/20)
(defparameter *ip-max* 4294967295)
(defun parse-range (string)
(mapcar #'parse-integer (split-sequence:split-sequence #\- string)))
(defun parse-ranges (data)
(mapcar #'parse-range data))
(defun range< (range1 range2)
(destructuring-bind (left1 right1) range1
(destructuring-bind (left2 right2) range2
(or (< left1 left2)
(and (= left1 left2)
(<= right1 right2))))))
(defun merge-overlapping (ranges)
(let ((sorted (sort (copy-seq ranges) #'range<)))
(loop with (merged-start merged-end) = (first sorted)
for (start end) in (rest sorted)
if (> (1- start) merged-end)
collect (list merged-start merged-end) into ranges
and do (setf merged-start start merged-end end)
else do (setf merged-end (max end merged-end))
finally (return (append ranges
(list (list merged-start merged-end)))))))
(define-solution (2016 20) (ranges parse-ranges)
(loop with part1 with part2 = (1+ *ip-max*)
for (start end) in (merge-overlapping ranges)
for size = (1+ (- end start)) do
(when (not part1) (setf part1 (1+ end)))
(decf part2 size)
finally (return (values part1 part2))))
(define-test (2016 20) (31053880 117))