Add day 02
[adventofcode2020.git] / src / day02.lisp
diff --git a/src/day02.lisp b/src/day02.lisp
new file mode 100644 (file)
index 0000000..fb93f03
--- /dev/null
@@ -0,0 +1,47 @@
+(in-package #:adventofcode2020)
+
+(defun valid-password-count? (pw-spec)
+  (destructuring-bind (count-str char-str passwd) (split " " pw-spec)
+    (let ((countp (destructuring-bind (count-low count-high) (mapcar #'parse-integer (split "-" count-str))
+                    (lambda (n)
+                      (<= count-low n count-high))))
+          (char-count (loop with char = (char char-str 0)
+                            for c across passwd
+                            summing (if (char= c char) 1 0))))
+      (funcall countp char-count))))
+
+(defun valid-password-index? (pw-spec)
+  (destructuring-bind (index-str char-str passwd) (split " " pw-spec)
+    (let* ((indices (mapcar (compose #'1- #'parse-integer) (split "-" index-str)))
+           (char (char char-str 0))
+           (get-char (lambda (n) (char passwd n))))
+      (->> (mapcar get-char indices)
+           (remove char)
+           (length)
+           (= 1)))))
+
+(day 02 input
+  (let ((pws-and-specs (list-from input)))
+    (part1 (->> pws-and-specs
+                (remove-if-not #'valid-password-count?)
+                (length)))
+    (part2 (->> pws-and-specs
+                (remove-if-not #'valid-password-index?)
+                (length)))))
+
+(def-suite day02)
+(in-suite day02)
+
+(test valid-password-count?
+  (is (equal
+        '(t nil t)
+        (mapcar #'valid-password-count?
+                '("1-3 a: abcde" "1-3 b: cdefg" "2-9 c: ccccccccc")))))
+
+(test valid-password-index?
+  (is (equal 
+        '(t nil nil) 
+        (mapcar #'valid-password-index? 
+                '("1-3 a: abcde" "1-3 b: cdefg" "2-9 c: ccccccccc")))))
+
+(run! 'day02)