summaryrefslogtreecommitdiff
path: root/8-2.scm
blob: 7e680449f88837998f9afcddc0ddb20543553de4 (plain)
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
#!/usr/bin/env -S guile -s
!#
(use-modules (ice-9 regex)
             (ice-9 textual-ports)
             (srfi srfi-1)
             (srfi srfi-69))

(define (read-lines port)
  (letrec ((loop (lambda (l ls)
                   (if (eof-object? l)
                       ls
                       (loop (get-line port) (cons l ls))))))
    (reverse (loop (get-line port) '()))))

(define (parse-line line)
  (let ((m (string-match "([A-Z]{3}) = \\(([A-Z]{3}), ([A-Z]{3})\\)" line)))
    `(,(match:substring m 1) (,(match:substring m 2) ,(match:substring m 3)))))

(define (find-node tag tree)
  (car (filter (lambda (x) (equal? tag (car x))) tree)))

(define (solve-path start tree instructions)
  (let ((current-instruction 0)
        (current-node start)
        (count 0))
    (while (not (equal? (string-ref current-node 2) #\Z))
      (if (equal? (string-ref instructions current-instruction) #\L)
          (set! current-node (caadr (find-node current-node tree)))
          (set! current-node (cadadr (find-node current-node tree))))
      (set! current-instruction (modulo (1+ current-instruction) (string-length instructions)))
      (set! count (1+ count)))
    count))

(let* ((port (open-input-file "8.txt"))
       (lines (read-lines port))
       (instructions (car lines))
       (tree (map parse-line (cddr lines)))
       (start-nodes (filter (lambda (x) (equal? (string-ref x 2) #\A)) (map car tree))))
  (close-port port)
  (display (apply lcm (map (lambda (x) (solve-path x tree instructions)) start-nodes))))