#!/usr/bin/env mzscheme ; Special thanks to Vixey in #lispcafe ; within? x lower upper ; Is x is within lower to upper? (define (within? x lower upper) (<= lower x upper)) ; wrap-range x lower upper ; If x is above range, it will wrap from lower ; If x is below range, it will wrap from upper ; It will repeat if necessary (define (wrap-range x lower upper) (cond ((> x upper) (wrap-range (+ lower (- x upper) -1) lower upper)) ((< x lower) (wrap-range (- upper (- lower x) -1) lower upper)) (else x))) ; rotate-char char amount lower upper -> char ; If char is within lower and upper range, increase char by amount, and if ; it goes over the upper range, then wrap around to the lower range. (define (rotate-char x amount lower upper) (let ((x (char->integer x)) (lower (char->integer lower)) (upper (char->integer upper))) (integer->char (if (within? x lower upper) (wrap-range (+ x amount) lower upper) x)))) ; rot13 x ; Converts char x to its rot13 equivalent (define (rot13 x) (cond ((char-lower-case? x) (rotate-char x 13 #\a #\z)) ((char-upper-case? in) (rotate-char x 13 #\A #\Z)) (else x))) ; rot13-string string ; Converts a string to its rot13 equivalent (define (rot13-string string) (list->string (map rot13 (string->list string))))