Commit | Line | Data |
---|---|---|
32679abf JK |
1 | (asdf:load-system :adventofcode2020) |
2 | (in-package #:adventofcode2020) | |
3 | (named-readtables:in-readtable fn-reader) | |
4 | ||
5 | (defun joltage-distribution (ratings) | |
6 | (let* ((extended (append '(0) ratings (mapcar λ(+ 3 _) (last ratings))))) | |
7 | (loop for a in extended | |
8 | for b in (cdr extended) | |
9 | counting (= 3 (- b a)) into threes | |
10 | counting (= 1 (- b a)) into ones | |
11 | finally (return (list ones threes))))) | |
12 | ||
13 | (defun partition-ratings (ratings) | |
14 | (let ((groups nil) (g nil)) | |
15 | (loop for a in ratings | |
16 | for b in (cdr (append ratings (mapcar λ(+ 3 _) (last ratings)))) | |
17 | do (push a g) | |
18 | when (= 3 (- b a)) | |
19 | do (progn | |
20 | (push (nreverse g) groups) | |
21 | (setf g nil))) | |
22 | (nreverse groups))) | |
23 | ||
24 | ; turns out you don't need the fancy memoized one | |
25 | ; (defparameter *count-deletions-table* | |
26 | ; (alist-hash-table '((1 . 0) (2 . 0) (3 . 1) (4 . 3)))) | |
27 | ; (defun count-deletions (len) | |
28 | ; (let ((val (gethash len *count-deletions-table*))) | |
29 | ; (if val val | |
30 | ; (let ((new-val (* 2 (count-deletions (1- len))))) | |
31 | ; (setf (gethash len *count-deletions-table*) new-val) | |
32 | ; new-val)))) | |
33 | (defun count-deletions (len) | |
34 | (case len | |
35 | (1 0) (2 0) (3 1) (4 3) | |
36 | (t (* 2 (count-deletions (1- len)))))) | |
37 | ||
38 | (defun count-adapter-arrangements (ratings) | |
39 | (reduce #'* (mapcar (compose #'1+ #'count-deletions #'length) | |
40 | (partition-ratings (cons 0 ratings))))) | |
41 | ||
42 | (day 10 input | |
43 | (let ((ratings (sort (int-list-from input) #'<))) | |
44 | (part1 (apply #'* (joltage-distribution ratings))) | |
45 | (part2 (count-adapter-arrangements ratings)))) | |
46 | ||
47 | (def-suite day10) | |
48 | (in-suite day10) | |
49 | ||
50 | (defvar *simple-ratings* | |
51 | (sort '(16 10 15 5 1 11 7 19 6 12 4) #'<)) | |
52 | ||
53 | (defvar *more-ratings* | |
54 | (sort '(28 33 18 42 31 14 46 20 48 47 | |
55 | 24 23 49 45 19 38 39 11 1 32 | |
56 | 25 35 8 17 7 9 4 2 34 10 3) #'<)) | |
57 | ||
58 | (test joltage-distributions | |
59 | (is (equal '(7 5) (joltage-distribution *simple-ratings*))) | |
60 | (is (equal '(22 10) (joltage-distribution *more-ratings*)))) | |
61 | ||
62 | (test partition-ratings | |
63 | (is (equal | |
64 | '((1) (4 5 6 7) (10 11 12) (15 16) (19)) | |
65 | (partition-ratings *simple-ratings*))) | |
66 | (is (equal | |
67 | '((1 2 3 4) (7 8 9 10 11) (14) (17 18 19 20) (23 24 25) | |
68 | (28) (31 32 33 34 35) (38 39) (42) (45 46 47 48 49)) | |
69 | (partition-ratings *more-ratings*)))) | |
70 | ||
71 | (test count-deletions | |
72 | (is (equal | |
73 | '(0 3 1 0 0) | |
74 | (mapcar (compose #'count-deletions #'length) | |
75 | '((0 1) (4 5 6 7) (10 11 12) (15 16) (19))))) | |
76 | (is (equal | |
77 | '(6 6 0 3 1 0 6 0 0 6) | |
78 | (mapcar (compose #'count-deletions #'length) | |
79 | '((0 1 2 3 4) (7 8 9 10 11) (14) (17 18 19 20) (23 24 25) | |
80 | (28) (31 32 33 34 35) (38 39) (42) (45 46 47 48 49)))))) | |
81 | ||
82 | (test count-adapter-arrangements | |
83 | (is (equal 8 (count-adapter-arrangements *simple-ratings*))) | |
84 | (is (equal 19208 (count-adapter-arrangements *more-ratings*)))) | |
85 | ||
86 | (run! 'day10) |