(define (count guess)
(with-input-from-file "sicp.md"
(lambda ()
(let loop ((prev #f)
(score 0))
(let ((current (read-char)))
(cond
((eof-object? current) score)
(else (loop current (if (eq? (guess prev) current)
(+ score 1)
score)))))))))
(define (make-list-matcher l)
(cond
((or (null? l)
(null? (cdr l)))
(lambda (prev) (values #f #f)))
(else
(let ((next (make-list-matcher (cdr l))))
(lambda (prev)
(if (eq? prev (car l))
(values (cadr l) next)
(values #f #f)))))))
(define (matcher string)
(make-list-matcher (string->list string)))
(define (match-any matchers prev)
(cond
((null? matchers) (values #f #f))
(else (call-with-values (lambda () ((car matchers) prev))
(lambda (response next)
(if (eq? response #f)
(match-any (cdr matchers) prev)
(values response next)))))))
(define (wizard default matchers)
(let ((prev #f))
(lambda (current)
(let ((m (if prev (cons prev matchers) matchers)))
(call-with-values (lambda () (match-any m current))
(lambda (response next)
(set! prev next)
(or response default)))))))
(count (wizard #\space '()))
;; 215505
(count (wizard #\space (list (matcher "Th"))))
;; 217444
(count (wizard #\space (list (matcher "Th")
(matcher "Scheme"))))
;; 218109
(count (wizard #\space (list (matcher "Th")
(matcher "Scheme")
(matcher "``` .{scheme}\n"))))
;; 219042
(count (wizard #\space (list (matcher "Th")
(matcher "Scheme")
(matcher "``` .{scheme}\n")
(matcher "))"))))
;; 221587
(count (wizard #\space (list (matcher "Th")
(matcher "Scheme")
(matcher "``` .{scheme}\n")
(matcher "))")
(matcher "(define"))))
;; 229572