summaryrefslogtreecommitdiff
path: root/10.scm
blob: b6b50b6894dded5501e71a29e0750bb380c9e4a5 (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
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/usr/bin/env -S guile -s
!#
(use-modules (ice-9 textual-ports)
             (srfi srfi-1))

(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 (candidates-for type pos)
  (let ((x (car pos))
        (y (cdr pos)))
    (cond ((equal? type #\|) `(,(cons x (1+ y))
                               ,(cons x (1- y))))
          ((equal? type #\-) `(,(cons (1+ x) y)
                               ,(cons (1- x) y)))
          ((equal? type #\L) `(,(cons x (1- y))
                               ,(cons (1+ x) y)))
          ((equal? type #\J) `(,(cons x (1- y))
                               ,(cons (1- x) y)))
          ((equal? type #\7) `(,(cons (1- x) y)
                               ,(cons x (1+ y))))
          ((equal? type #\F) `(,(cons x (1+ y))
                               ,(cons (1+ x) y)))
          ((equal? type #\S) `(,(cons x (1+ y))
                               ,(cons x (1- y))
                               ,(cons (1+ x) y)
                               ,(cons (1- x) y)))
          ((equal? type #\.) '()))))

(let* ((port (open-input-file "10.txt"))
       (lines (read-lines port))
       (candidates '(((0 . 2) . 0)))
       (seen '())
       (last #nil)
       (start 0))
  (close-port port)
  (do ((i 0 (1+ i))) ((string-contains (list-ref lines i) "S")) (set! start i))
  (set! candidates `(,(cons (cons (string-index (list-ref lines (1+ start)) #\S) (1+ start)) 0)))
  (while (not (null? candidates))
    (set! seen (append! seen `(,(caar candidates))))
    (let* ((cands (candidates-for (string-ref (list-ref lines (cdaar candidates)) (caaar candidates)) (caar candidates)))
           (cands (filter (lambda (x) (and (not (member x seen))
                                           (not (negative? (car x)))
                                           (not (negative? (cdr x)))
                                           (member (caar candidates) (candidates-for (string-ref (list-ref lines (cdr x)) (car x)) x)))) cands))
           (cands (map (lambda (x) (cons (cons (car x) (cdr x)) (1+ (cdar candidates)))) cands)))
      (set! last (car candidates))
      (set! candidates (append! (cdr candidates) cands))))
  (display (cdr last)))