aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--day25.scm62
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!")