; scrambled words
(define (shuffle x)
(do ((v (list->vector x)) (n (length x) (- n 1)))
((zero? n) (vector->list v))
(let* ((r (random n)) (t (vector-ref v r)))
(vector-set! v r (vector-ref v (- n 1)))
(vector-set! v (- n 1) t))))
(define (scramble str)
(let* ((cs (string->list str))
(upper (map char-upper-case? cs))
(cs (map char-downcase cs)))
(let loop ((cs cs) (word (list)) (zs (list)))
(cond ((null? cs) ; end of input
(list->string
(map (lambda (u? c)
(if u? (char-upcase c) c))
upper (reverse zs))))
((and ; collect letter into accumulator
(pair? zs)
(char-alphabetic? (car zs))
(char-alphabetic? (car cs))
(pair? (cdr cs))
(char-alphabetic? (cadr cs)))
(loop (cdr cs) (cons (car cs) word) zs))
((pair? word) ; end of word interior
(loop (cddr cs) (list)
(append (list (cadr cs))
(list (car cs))
(shuffle word) zs)))
(else ; not in a word
(loop (cdr cs) word (cons (car cs) zs)))))))
(display (scramble "Programming Praxis is fun!")) (newline)
(display (scramble "Programming Praxis is fun!")) (newline)
(display (scramble "Programming Praxis is fun!")) (newline)