; odometer

(define (next-char c)
  (integer->char (+ (char->integer c) 1)))

(define (next1 c)
  (cond ((char=? c #\Z) (values #\A #t))
        ((char=? c #\9) (values #\0 #t))
        (else (values (next-char c) #f))))

(define (next str)
  (let loop ((cs (reverse (string->list str))) (xs (list)) (carry? #f))
    (if (null? cs) (list->string (reverse xs))
      (call-with-values
        (lambda () (next1 (car cs)))
        (lambda (x carry?)
          (if carry?  (loop (cdr cs) (cons x xs) #f)
            (list->string  (append (reverse (cdr cs)) (cons x xs)))))))))

(display (next "123")) (newline)
(display (next "199")) (newline)
(display (next "999")) (newline)
(display (next "ABC")) (newline)
(display (next "FZZ")) (newline)
(display (next "G7TS39")) (newline)