(define-module (day25) #:use-module (ice-9 rdelim) #:use-module (rnrs io ports) #:use-module (srfi srfi-1) #:use-module (srfi srfi-43)) (define +block-chars+ (char-set #\# #\.)) (define (read-key-or-lock port topc expect-end) (define vec (make-vector 5 0)) (let iter ((i 0)) (unless (= i 5) (let ((line (read-line port))) (when (eof-object? line) (error "Unexpected EOF in the middle of a key.")) (unless (string-every +block-chars+ line) (error "Lines in keys/locks must be '#' or '.'." line)) (let jiter ((j 0)) (unless (= j 5) (when (char=? topc (string-ref line j)) (unless (= i (vector-ref vec j)) (error (string-append "Columns must be all '#' followed by all '.' " "or vice versa; cannot alternate.") vec line i j)) (vector-set! vec j (+ i 1))) (jiter (+ j 1))))) (iter (+ i 1)))) (define end-line (read-line port)) (unless (equal? end-line expect-end) (error "Expected key/lock end line to be ~a; got ~a." expect-end end-line)) (define blank (read-line port)) (unless (or (eof-object? blank) (string=? "" blank)) (error "Expected blank line or end-of-file." blank)) vec) (define (read-key port) (define line (read-line port)) (cond ((or (eof-object? line) (string=? "" line)) (values (eof-object) (eof-object))) ((string=? line ".....") (values 'key (read-key-or-lock port #\. "#####"))) ((string=? line "#####") (values 'lock (read-key-or-lock port #\# "....."))) (else (error "Expected key ('.....') or lock ('#####')." line)))) (define (read-input port) (let iter ((keys '()) (locks '())) (define-values (type vec) (read-key port)) (cond ((eof-object? type) (values keys locks)) ((eq? type 'key) (iter (cons vec keys) locks)) (else (iter keys (cons vec locks)))))) (define (part1 port) (define-values (keys locks) (read-input port)) (fold (lambda (key cnt) (fold (lambda (lock cnt) (if (vector-every >= key lock) (+ cnt 1) cnt)) cnt locks)) 0 keys)) (define (part2 port) "yay!")