Created
December 6, 2020 11:18
-
-
Save death/ed7980ce7a932585a241a9fffdc2da83 to your computer and use it in GitHub Desktop.
aoc2020 day6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;;;; +----------------------------------------------------------------+ | |
| ;;;; | Advent of Code 2020 | | |
| ;;;; +----------------------------------------------------------------+ | |
| (defpackage #:snippets/aoc2020/day6 | |
| (:use #:cl) | |
| (:shadowing-import-from | |
| #:fset | |
| #:set | |
| #:empty-set | |
| #:convert | |
| #:union | |
| #:intersection | |
| #:size) | |
| (:export | |
| #:day6)) | |
| (in-package #:snippets/aoc2020/day6) | |
| (defstruct group | |
| (some (empty-set)) | |
| (every (empty-set)) | |
| (members 0)) | |
| (defun parse (input) | |
| (mapcar #'parse-group input)) | |
| (defun parse-group (strings) | |
| (reduce #'group-add strings :initial-value (make-group))) | |
| (defun group-add (group answer-string) | |
| (let ((answers (convert 'set answer-string))) | |
| (make-group :some (union (group-some group) answers) | |
| :every (if (zerop (group-members group)) | |
| answers | |
| (intersection (group-every group) answers)) | |
| :members (1+ (group-members group))))) | |
| (defun group-count-some (group) | |
| (size (group-some group))) | |
| (defun group-count-every (group) | |
| (size (group-every group))) | |
| (defun sum (sequence &key (key #'identity)) | |
| (reduce #'+ sequence :key key)) | |
| (defun day6 (input) | |
| (let ((groups (parse input))) | |
| (list (sum groups :key #'group-count-some) | |
| (sum groups :key #'group-count-every)))) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;; About the input expected by the solving program | |
| ;; | |
| ;; I wrote a regression tester for puzzles such as Advent of Code, | |
| ;; which reads files containing puzzle input and output, loads the | |
| ;; solving program, and compares its computed output to the stored | |
| ;; output. | |
| ;; | |
| ;; Many puzzles have similar input structure, e.g. lines of text or | |
| ;; lists of numbers. I exploit this by having the regression tester | |
| ;; preprocess the input prior to passing it to the solving program. | |
| ;; | |
| ;; With this puzzle I added a new preprocessing function, | |
| ;; grouped-lines (see below), which means my solving program can | |
| ;; expect a list of lists of lines, given that I add a test for it | |
| ;; like this: | |
| ;; | |
| ;; (add-test (aoc 2020 6 :input-transform #'grouped-lines)) | |
| (defun grouped-lines (string) | |
| "Return a list of lists of lines in STRING. | |
| Empty lines serve as group delimiters." | |
| (let ((lines (lines string)) | |
| (group '()) | |
| (groups '())) | |
| (flet ((add-group () | |
| (when group | |
| (push (nreverse group) groups) | |
| (setf group '())))) | |
| (dolist (line lines) | |
| (if (equal line "") | |
| (add-group) | |
| (push line group))) | |
| (add-group) | |
| (nreverse groups)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment