; n-gram frequency

(define (uniq-c eql? xs)
  (if (null? xs) xs
    (let loop ((xs (cdr xs)) (prev (car xs)) (k 1) (result '()))
      (cond ((null? xs) (reverse (cons (cons prev k) result)))
            ((eql? (car xs) prev) (loop (cdr xs) prev (+ k 1) result))
            (else (loop (cdr xs) (car xs) 1 (cons (cons prev k) result)))))))

(define (freq str . size)
  (let ((size (if (pair? size) (car size) 1)))
    (do ((i 0 (+ i 1)) (blocks (list) (cons (substring str i (+ i size)) blocks)))
        ((< (string-length str) (+ i size)) (uniq-c string=? (sort blocks string<?))))))

(display (freq "Programming Praxis" 2)) (newline)