; 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)