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