Skip to content

Instantly share code, notes, and snippets.

@qookei
Created December 8, 2023 18:16
Show Gist options
  • Save qookei/02d9f2bd82b31bd70936659ed375ef13 to your computer and use it in GitHub Desktop.
Save qookei/02d9f2bd82b31bd70936659ed375ef13 to your computer and use it in GitHub Desktop.
(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