Created
December 8, 2023 18:16
-
-
Save qookei/02d9f2bd82b31bd70936659ed375ef13 to your computer and use it in GitHub Desktop.
This file contains 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
(use-modules (srfi srfi-1) (ice-9 textual-ports) (ice-9 peg) | |
(ice-9 format) (ice-9 match) (ice-9 pretty-print)) | |
(define-peg-string-patterns | |
"path <- ('L'/'R')+ NL | |
node <-- name EQ LPAREN name COMMA name RPAREN NL | |
name <-- ([A-Z0-9])+ | |
EQ < ' = ' | |
LPAREN < '(' | |
RPAREN < ')' | |
COMMA < ', ' | |
NL < '\n'") | |
(define-peg-pattern top all (peg "path NL node+ !.")) | |
(define (process-node tree) | |
(cons (cadr (second tree)) | |
(cons (cadr (third tree)) | |
(cadr (fourth tree))))) | |
(define (process-tree tree) | |
(cons (second tree) | |
(map process-node (third tree)))) | |
(define (%count-steps-toward done? cur-path full-path cur-node tree acc) | |
(let ([edges (cdr (assoc cur-node tree))]) | |
(cond | |
[(done? cur-node) acc] | |
[(string-null? cur-path) (%count-steps-toward done? full-path full-path cur-node tree acc)] | |
[else | |
(%count-steps-toward | |
done? | |
(string-drop cur-path 1) | |
full-path | |
(match (string-take cur-path 1) | |
["L" (car edges)] | |
["R" (cdr edges)]) | |
tree | |
(1+ acc))]))) | |
(define (count-steps-toward source done? path tree) | |
(%count-steps-toward done? path path source tree 0)) | |
(define (part1-initial? node) | |
(string=? "AAA" node)) | |
(define (part1-terminal? node) | |
(string=? "ZZZ" node)) | |
(define (part2-initial? node) | |
(string-suffix? "A" node)) | |
(define (part2-terminal? node) | |
(string-suffix? "Z" node)) | |
(define (part-common input initial-node? terminal-node?) | |
(let ([nodes (filter initial-node? (map car (cdr input)))]) | |
(apply lcm | |
(map (λ (node) | |
(count-steps-toward | |
node | |
terminal-node? | |
(car input) (cdr input))) | |
nodes)))) | |
(let* ([input (get-string-all (current-input-port))] | |
[peg-tree (peg:tree (match-pattern top input))] | |
[tree (process-tree peg-tree)]) | |
(format #t "Part 1: ~a~%" (part-common tree part1-initial? part1-terminal?)) | |
(format #t "Part 2: ~a~%" (part-common tree part2-initial? part2-terminal?))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment