aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Marín Noguera <juan@mnpi.eu>2024-12-07 19:13:35 +0100
committerJuan Marín Noguera <juan@mnpi.eu>2024-12-07 19:13:35 +0100
commitc50cc5ff27a95e9317817c0669ca882511fd67f2 (patch)
treeaa597d36170fb9a3ada32e3ae7f9829029ce4955
parent988f4f31486b2b6a121a2da9316736bd0a585f50 (diff)
Day 07
Lesson learned, the one from Day 06
-rw-r--r--day07.scm53
1 files changed, 53 insertions, 0 deletions
diff --git a/day07.scm b/day07.scm
new file mode 100644
index 0000000..e5fdf52
--- /dev/null
+++ b/day07.scm
@@ -0,0 +1,53 @@
+(define-module (day07)
+ #:use-module (ice-9 match)
+ #:use-module (ice-9 rdelim)
+ #:use-module (ice-9 regex)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-9))
+
+(define +eq-regex+ (make-regexp "^([0-9]+): ([0-9]+( [0-9]+)*)$"))
+
+(define-record-type
+ <equation> (make-equation result operands) equation?
+ (result equation-result)
+ (operands equation-operands))
+
+(define* (parse-equation line)
+ (define mtch (regexp-exec +eq-regex+ line))
+ (unless mtch
+ (error "Expected equation like \"<result>: <op1> [op2] ...\"." line))
+ (make-equation (string->number (match:substring mtch 1))
+ (map string->number
+ (string-split (match:substring mtch 2) #\space))))
+
+(define (equation-plausible? equation . ops)
+ (define result (equation-result equation))
+ (define (attempt? lst)
+ (cond ((null? (cdr lst)) (= (car lst) result))
+ ((> (car lst) result) #f)
+ (else (match-let (((fst snd . rest) lst))
+ (any (lambda (op) (attempt? (cons (op fst snd) rest)))
+ ops)))))
+ (attempt? (equation-operands equation)))
+
+(define (ex-iter port acc nlines pred)
+ (define line (read-line port))
+ (when (zero? (modulo nlines 100))
+ (format #t "Parsing line ~a...\n" nlines))
+ (if (or (eof-object? line) (string= "" line))
+ acc
+ (let ((eq (parse-equation line)))
+ (ex-iter port (if (pred eq)
+ (+ acc (equation-result eq))
+ acc)
+ (+ nlines 1)
+ pred))))
+
+(define* (part1 #:optional (port (current-input-port)))
+ (ex-iter port 0 1 (lambda (eq) (equation-plausible? eq + *))))
+
+(define (|| n1 n2)
+ (string->number (string-append (number->string n1) (number->string n2))))
+
+(define* (part2 #:optional (port (current-input-port)))
+ (ex-iter port 0 1 (lambda (eq) (equation-plausible? eq + * ||))))