Add cl-interpol
[adventofcode2020.git] / src / day02.lisp
1 (asdf:load-system :adventofcode2020)
2 (in-package #:adventofcode2020)
3
4 (defun valid-password-count? (pw-spec)
5 (destructuring-bind (count-str char-str passwd) (split " " pw-spec)
6 (let ((countp (destructuring-bind (count-low count-high) (mapcar #'parse-integer (split "-" count-str))
7 (lambda (n)
8 (<= count-low n count-high))))
9 (char-count (loop with char = (char char-str 0)
10 for c across passwd
11 summing (if (char= c char) 1 0))))
12 (funcall countp char-count))))
13
14 (defun valid-password-index? (pw-spec)
15 (destructuring-bind (index-str char-str passwd) (split " " pw-spec)
16 (let* ((indices (mapcar (compose #'1- #'parse-integer) (split "-" index-str)))
17 (char (char char-str 0))
18 (get-char (lambda (n) (char passwd n))))
19 (->> (mapcar get-char indices)
20 (remove char)
21 (length)
22 (= 1)))))
23
24 (day 02 input
25 (let ((pws-and-specs (list-from input)))
26 (part1 (->> pws-and-specs
27 (remove-if-not #'valid-password-count?)
28 (length)))
29 (part2 (->> pws-and-specs
30 (remove-if-not #'valid-password-index?)
31 (length)))))
32
33 (def-suite day02)
34 (in-suite day02)
35
36 (test valid-password-count?
37 (is (equal
38 '(t nil t)
39 (mapcar #'valid-password-count?
40 '("1-3 a: abcde" "1-3 b: cdefg" "2-9 c: ccccccccc")))))
41
42 (test valid-password-index?
43 (is (equal
44 '(t nil nil)
45 (mapcar #'valid-password-index?
46 '("1-3 a: abcde" "1-3 b: cdefg" "2-9 c: ccccccccc")))))
47
48 (run! 'day02)