]> localhost Git - adventofcode2020.git/commitdiff
Add day 10
authorJack Kinsey <j.jameskinsey@gmail.com>
Fri, 11 Dec 2020 07:10:38 +0000 (02:10 -0500)
committerJack Kinsey <j.jameskinsey@gmail.com>
Fri, 11 Dec 2020 07:10:38 +0000 (02:10 -0500)
res/day10 [new file with mode: 0644]
src/day10.lisp [new file with mode: 0644]

diff --git a/res/day10 b/res/day10
new file mode 100644 (file)
index 0000000..ec74d95
--- /dev/null
+++ b/res/day10
@@ -0,0 +1,99 @@
+18
+47
+144
+147
+124
+45
+81
+56
+16
+59
+97
+83
+75
+150
+33
+165
+30
+159
+84
+141
+104
+25
+164
+90
+92
+88
+2
+8
+51
+24
+153
+63
+27
+123
+127
+58
+108
+52
+38
+15
+149
+66
+72
+21
+46
+89
+135
+55
+34
+37
+78
+65
+134
+148
+76
+138
+103
+162
+114
+109
+42
+77
+102
+163
+7
+105
+69
+39
+91
+111
+131
+130
+6
+137
+96
+82
+64
+3
+95
+136
+85
+9
+116
+17
+99
+12
+117
+62
+50
+110
+26
+115
+71
+57
+156
+120
+98
+1
+70
diff --git a/src/day10.lisp b/src/day10.lisp
new file mode 100644 (file)
index 0000000..5359b46
--- /dev/null
@@ -0,0 +1,86 @@
+(asdf:load-system :adventofcode2020)
+(in-package #:adventofcode2020)
+(named-readtables:in-readtable fn-reader)
+
+(defun joltage-distribution (ratings)
+  (let* ((extended (append '(0) ratings (mapcar λ(+ 3 _) (last ratings)))))
+    (loop for a in extended
+          for b in (cdr extended)
+          counting (= 3 (- b a)) into threes
+          counting (= 1 (- b a)) into ones
+          finally (return (list ones threes)))))
+
+(defun partition-ratings (ratings)
+  (let ((groups nil) (g nil))
+    (loop for a in ratings
+          for b in (cdr (append ratings (mapcar λ(+ 3 _) (last ratings))))
+          do (push a g)
+          when (= 3 (- b a))
+          do (progn
+               (push (nreverse g) groups)
+               (setf g nil)))
+    (nreverse groups)))
+
+; turns out you don't need the fancy memoized one
+; (defparameter *count-deletions-table*
+;   (alist-hash-table '((1 . 0) (2 . 0) (3 . 1) (4 . 3))))
+; (defun count-deletions (len)
+;   (let ((val (gethash len *count-deletions-table*)))
+;     (if val val
+;         (let ((new-val (* 2 (count-deletions (1- len)))))
+;           (setf (gethash len *count-deletions-table*) new-val)
+;           new-val))))
+(defun count-deletions (len)
+  (case len
+    (1 0) (2 0) (3 1) (4 3)
+    (t (* 2 (count-deletions (1- len))))))
+
+(defun count-adapter-arrangements (ratings)
+  (reduce #'* (mapcar (compose #'1+ #'count-deletions #'length)
+                      (partition-ratings (cons 0 ratings)))))
+
+(day 10 input
+  (let ((ratings (sort (int-list-from input) #'<)))
+    (part1 (apply #'* (joltage-distribution ratings)))
+    (part2 (count-adapter-arrangements ratings))))
+
+(def-suite day10)
+(in-suite day10)
+
+(defvar *simple-ratings*
+  (sort '(16 10 15 5 1 11 7 19 6 12 4) #'<))
+
+(defvar *more-ratings*
+  (sort '(28 33 18 42 31 14 46 20 48 47
+          24 23 49 45 19 38 39 11 1 32
+          25 35 8 17 7 9 4 2 34 10 3) #'<))
+
+(test joltage-distributions
+  (is (equal '(7 5) (joltage-distribution *simple-ratings*)))
+  (is (equal '(22 10) (joltage-distribution *more-ratings*))))
+
+(test partition-ratings
+  (is (equal
+        '((1) (4 5 6 7) (10 11 12) (15 16) (19))
+        (partition-ratings *simple-ratings*)))
+  (is (equal
+        '((1 2 3 4) (7 8 9 10 11) (14) (17 18 19 20) (23 24 25) 
+                    (28) (31 32 33 34 35) (38 39) (42) (45 46 47 48 49))
+        (partition-ratings *more-ratings*))))
+
+(test count-deletions
+  (is (equal
+        '(0 3 1 0 0)
+        (mapcar (compose #'count-deletions #'length)
+                '((0 1) (4 5 6 7) (10 11 12) (15 16) (19)))))
+  (is (equal
+        '(6 6 0 3 1 0 6 0 0 6)
+        (mapcar (compose #'count-deletions #'length)
+                '((0 1 2 3 4) (7 8 9 10 11) (14) (17 18 19 20) (23 24 25) 
+                    (28) (31 32 33 34 35) (38 39) (42) (45 46 47 48 49))))))
+
+(test count-adapter-arrangements
+  (is (equal 8 (count-adapter-arrangements *simple-ratings*)))
+  (is (equal 19208 (count-adapter-arrangements *more-ratings*))))
+
+(run! 'day10)