src/2020/days/day-07.lisp @ 2848a4548adf
2023/01 and 2022/01 Also start porting my test data to the new account, since Twitter imploded and apparently it's impossible for a website to store a goddamn username and password in The Year of Our Lord 2023 so everyone just outsources auth all the time, ugh.
| author | Steve Losh <steve@stevelosh.com> |
|---|---|
| date | Fri, 01 Dec 2023 11:05:43 -0500 |
| parents | ff7c8ed35992 |
| children | (none) |
(advent:defpackage* :advent/2020/07) (in-package :advent/2020/07) (defun parse-contained (string) (ppcre:register-groups-bind (n color) ("^(\\d+) (.+) bags?$" string) (cons color (parse-integer n)))) (defun parse-contents (string) (if (string= "no other bags" string) (list) (mapcar #'parse-contained (str:split ", " string)))) (defun parse-line (line) (ppcre:register-groups-bind (container contents) ("^(.+) bags contain (.+)[.]$" line) (cons container (parse-contents contents)))) (defun parse-data (stream) ;; { container: { contained: n, … }, … } (iterate (for line :in-stream stream :using #'read-line) (for (container . contents) = (parse-line line)) (collect-hash (container (alexandria:alist-hash-table contents :test #'equal)) :test #'equal))) (defun reachablep (rules goal start) (astar :start start :neighbors (lambda (state) (alexandria:hash-table-keys (gethash state rules))) :goalp (curry #'equal goal) :cost (constantly 1) :heuristic (constantly 1) :test #'equal)) (defun count-required (rules start) (recursively ((current start)) (1+ (iterate (for (child n) :in-hashtable (gethash current rules)) (summing (* n (recur child))))))) (define-problem (2020 7) (rules parse-data) (192 12128) (values (count-if (curry #'reachablep rules "shiny gold") (remove "shiny gold" (alexandria:hash-table-keys rules) :test #'string=)) (1- (count-required rules "shiny gold")))) #; Scratch --------------------------------------------------------------------