(import (rnrs) (only (chezscheme) make-parameter parameterize printf)) (define filename (make-parameter "in/day1")) (define (string-reverse str) (list->string (reverse (string->list str)))) (define default-numbers '(("one" . 1) ("two" . 2) ("three" . 3) ("four" . 4) ("five" . 5) ("six" . 6) ("seven" . 7) ("eight" . 8) ("nine" . 9))) (define numbers (make-parameter default-numbers)) (define (digit? c) (and (char<=? #\0 c #\9) c)) (define (digit-val c) (- (char->integer c) (char->integer #\0))) (define (at? start short&val long) (let* [(short (car short&val)) (val (cdr short&val)) (end (+ start (string-length short)))] (cond [(> end (string-length long)) #f] [(string=? short (substring long start end)) val] [else #f]))) (define (find-first str) (let loop [(i 0)] (cond [(digit? (string-ref str i)) => digit-val] [(exists (lambda (n) (at? i n str)) (numbers))] [else (loop (+ i 1))]))) (define (find-last str) (let* [(rev-car (lambda (p) (cons (string-reverse (car p)) (cdr p)))) (rnums (map rev-car (numbers))) (rstr (string-reverse str))] (parameterize [(numbers rnums)] (find-first rstr)))) (define (make-value first last) (+ (* 10 first) last)) (define (value line) (make-value (find-first line) (find-last line))) (define (value1 line) (parameterize [(numbers '())] (value line))) (define (value2 line) (parameterize [(numbers default-numbers)] (value line))) (define (all-lines file) (let [(next (lambda () (get-line file)))] (do [(line (next) (next)) (acc '() (cons line acc))] [(eof-object? line) (reverse acc)]))) (define (input) (call-with-input-file (filename) all-lines)) (define (part1 input) (apply + (map value1 input))) (define (part2 input) (apply + (map value2 input))) (let [(in (input))] (printf "~a~n~a~n" (part1 in) (part2 in)))