-
Notifications
You must be signed in to change notification settings - Fork 0
/
day7.lisp
43 lines (38 loc) · 1.77 KB
/
day7.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
(in-package #:advent2020)
(defun read-bag-rules ()
(let ((graph (make-hash-table :test 'equal)))
(loop for rule in (uiop:read-file-lines
(asdf:system-relative-pathname 'advent2020 "inputs/day7"))
do (register-groups-bind (color rest-of-rule)
("^\(\\w+ \\w+\) bags contain \(.*\)" rule)
;; (format t "~A: ~A~%" color rest-of-rule)
(setf (gethash color graph)
(loop for rule-part in (split-sequence #\, rest-of-rule)
;; do (format t "~A~%" rule-part)
collect (register-groups-bind ((#'parse-integer n) c-color)
("\(\\d+\) \(\\w+ \\w+\) bag" rule-part)
(cons c-color n))))))
graph))
(defun path (graph start end)
(defun path-using (graph start end node-list)
(if (equal start end)
(return-from path (car (reverse node-list)))
(dolist (child (mapcar #'car (gethash start graph)))
(path-using graph child end (cons child node-list)))))
(path-using graph start end (list start)))
(defun day7/solution1 ()
(let ((graph (read-bag-rules))
(solutions 0))
(loop for color being the hash-keys of graph
when (and (not (string= color "shiny gold"))
(path graph color "shiny gold"))
do (incf solutions)
finally (return solutions))))
(defun total-bags (start bag-rules)
(+ 1 (loop for (color . quantity) in (gethash start bag-rules)
when (numberp quantity)
sum (* quantity (total-bags color bag-rules)))))
(defun day7/solution2 ()
;; subtracting 1 because we don't want to count the
;; shiny gold bag
(- (total-bags "shiny gold" (read-bag-rules)) 1))