; 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)
OyBuLWdyYW0gZnJlcXVlbmN5CgooZGVmaW5lICh1bmlxLWMgZXFsPyB4cykKICAoaWYgKG51bGw/IHhzKSB4cwogICAgKGxldCBsb29wICgoeHMgKGNkciB4cykpIChwcmV2IChjYXIgeHMpKSAoayAxKSAocmVzdWx0ICcoKSkpCiAgICAgIChjb25kICgobnVsbD8geHMpIChyZXZlcnNlIChjb25zIChjb25zIHByZXYgaykgcmVzdWx0KSkpCiAgICAgICAgICAgICgoZXFsPyAoY2FyIHhzKSBwcmV2KSAobG9vcCAoY2RyIHhzKSBwcmV2ICgrIGsgMSkgcmVzdWx0KSkKICAgICAgICAgICAgKGVsc2UgKGxvb3AgKGNkciB4cykgKGNhciB4cykgMSAoY29ucyAoY29ucyBwcmV2IGspIHJlc3VsdCkpKSkpKSkKCihkZWZpbmUgKGZyZXEgc3RyIC4gc2l6ZSkKICAobGV0ICgoc2l6ZSAoaWYgKHBhaXI/IHNpemUpIChjYXIgc2l6ZSkgMSkpKQogICAgKGRvICgoaSAwICgrIGkgMSkpIChibG9ja3MgKGxpc3QpIChjb25zIChzdWJzdHJpbmcgc3RyIGkgKCsgaSBzaXplKSkgYmxvY2tzKSkpCiAgICAgICAgKCg8IChzdHJpbmctbGVuZ3RoIHN0cikgKCsgaSBzaXplKSkgKHVuaXEtYyBzdHJpbmc9PyAoc29ydCBibG9ja3Mgc3RyaW5nPD8pKSkpKSkKCihkaXNwbGF5IChmcmVxICJQcm9ncmFtbWluZyBQcmF4aXMiIDIpKSAobmV3bGluZSk=