aboutsummaryrefslogtreecommitdiff
path: root/day03.scm
diff options
context:
space:
mode:
Diffstat (limited to 'day03.scm')
-rw-r--r--day03.scm43
1 files changed, 43 insertions, 0 deletions
diff --git a/day03.scm b/day03.scm
new file mode 100644
index 0000000..983d8b5
--- /dev/null
+++ b/day03.scm
@@ -0,0 +1,43 @@
+(define-module (day03)
+ #:use-module (srfi srfi-41)
+ #:use-module (ice-9 match)
+ #:use-module (ice-9 rdelim)
+ #:use-module (ice-9 regex)
+ #:export (part1 part2))
+
+(define mul-regexp (make-regexp "mul\\(([0-9]+),([0-9]+)\\)|do\\(\\)|(don't\\(\\))"))
+
+(define (parse-instruction match)
+ (cond ((match:start match 3) 'dont)
+ ((match:start match 1) (list 'mul
+ (string->number (match:substring match 1))
+ (string->number (match:substring match 2))))
+ (else 'do)))
+
+(define* (input-instructions #:optional (port (current-input-port)))
+ (stream-let loop ((line (read-line port)) (start 0))
+ (if (eof-object? line)
+ stream-null
+ (let ((mch (regexp-exec mul-regexp line start)))
+ (if mch
+ (stream-cons (parse-instruction mch)
+ (loop line (match:end mch)))
+ (loop (read-line port) 0))))))
+
+(define (mul-op? x)
+ (and (pair? x) (eq? 'mul (car x))))
+
+(define* (part1 #:optional (port (current-input-port)))
+ (stream-fold + 0
+ (stream-map (lambda (op) (apply * (cdr op)))
+ (stream-filter mul-op? (input-instructions port)))))
+
+(define* (part2 #:optional (port (current-input-port)))
+ (let ((sum 0) (on? #t))
+ (stream-for-each
+ (match-lambda
+ ('do (set! on? #t))
+ ('dont (set! on? #f))
+ (('mul x y) (when on? (set! sum (+ sum (* x y))))))
+ (input-instructions port))
+ sum))