private: Yes


(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