blob: 174a5a78580cfe916fbaa390a916742b4c24e907 (
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
54
55
56
57
58
59
60
|
(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 (backtrack-fast equation concat?)
(define (attempt? lst result)
(if (null? (cdr lst))
(= (car lst) result)
(or (let ((x (/ result (car lst))))
(and (integer? x) (attempt? (cdr lst) x)))
(and concat?
(let ((res (number->string result))
(x (number->string (car lst))))
(and (string-suffix? x res)
(> (string-length res) (string-length x))
(attempt? (cdr lst)
(string->number
(substring res 0
(- (string-length res)
(string-length x))))))))
(let ((diff (- result (car lst))))
(and (not (negative? diff)) (attempt? (cdr lst) diff))))))
(attempt? (reverse (equation-operands equation)) (equation-result equation)))
(define (ex-iter port acc nlines concat?)
(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 (backtrack-fast eq concat?)
(+ acc (equation-result eq))
acc)
(+ nlines 1)
concat?))))
(define* (part1 #:optional (port (current-input-port)))
(ex-iter port 0 1 #f))
(define* (part2 #:optional (port (current-input-port)))
(ex-iter port 0 1 #t))
|