diff options
| author | Juan Marín Noguera <juan@mnpi.eu> | 2024-12-25 17:54:29 +0100 |
|---|---|---|
| committer | Juan Marín Noguera <juan@mnpi.eu> | 2024-12-25 17:54:29 +0100 |
| commit | 76e0578fdaee3aacc93af89ff1a3976f062187e7 (patch) | |
| tree | c73f9581c12bfd6133964a9219a672189dc8c832 | |
| parent | ae3cd22598a125db565c2fbaef8e1934754d29ad (diff) | |
| -rw-r--r-- | day25.scm | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/day25.scm b/day25.scm new file mode 100644 index 0000000..57cdb9d --- /dev/null +++ b/day25.scm @@ -0,0 +1,62 @@ +(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!") |
