blob: e5fdf52c8acc3b31751ee2f7a10812f8a2972aac (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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 + * ||))))
|