#!/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)))