aboutsummaryrefslogtreecommitdiff
path: root/03/2.scm
blob: 96eda2985b2ef8b74f6635d39a36d7ce18e7e0fa (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
(import (chicken io))
(import regex)
(import matchable)
(import (chicken string))

(define in-str
  (with-input-from-file "input" read-string))

;; (display in-str)
(define re
  "mul\\([0-9]+,[0-9]+\\)|do\\(\\)|don't\\(\\)")

(define matched
  (let loop ((start 0) (result '()))
    (define search-ret (string-search re in-str start))
    (if (not search-ret)
        (reverse result)
        (loop (cadar (string-search-positions re in-str start))
              (cons (car search-ret) result)))))

(define (extract-numbers str)
  (define nums-str (substring str 4 (- (string-length str) 1)))
  (map string->number (string-split nums-str ",")))

(define (process-instr str)
  (cond ((string-search "mul" str) (extract-numbers str))
        ((string-search "do\\(" str) 'do)
        (else 'dont)))

(define (calculate str)
  (define vals (extract-numbers str))
  (* (car vals) (cadr vals)))

(define sum
  (let loop ((is-do #t)
             (lst (map process-instr matched))
             (ret 0))
    (match lst
      (() ret)
      (('do . r) (loop #t r ret))
      (('dont . r) (loop #f r ret))
      (((a b) . r) (if is-do
                  (loop is-do r (+ ret (* a b)))
                  (loop is-do r ret))))))

(display sum)