[plt-dev] I love Haskell (not an April Fools Joke!), feature request for 'for'
So Mr Fortran-Hakell has posted another combinator version of the
code, and I approximated it in PLT.
#|
import Data.List
import GHC.Exts
main = do print $ rail 4 "PROGRAMMING PRAXIS"
print . derail 4 $ rail 4 "PROGRAMMING PRAXIS"
rail :: Int -> [a] -> [a]
rail n = zipSort (cycle $ [1..n] ++ [n-1,n-2..2])
derail :: Ord a => Int -> [a] -> [a]
derail n s = zipSort (rail n $ zipWith const [0..] s) s
zipSort :: Ord a => [a] -> [b] -> [b]
zipSort ks = map snd . sortWith fst . zip ks
|#
;; String Nat -> String
;; encrypt according to fence shape
(define (encrypt ls n)
(list->string (wave ls n)))
;; String Nat -> String
;; decrypt according to fence shape
(define (decrypt s n)
(list->string
(sort2 (wave (for/list ((i (in-naturals)) (c s)) i) n) (string-
>list s))))
;; [Listof X] Nat -> [Listof X]
;; create a wave from the list, depth n
;; [needed because in Scheme, string != (Listof Char)]
(define (wave ls n)
(sort2 (in-list (shared ((x (append (range 1 n) (range (- n 1) 2)
x))) x)) ls))
;; [Listof Nat] [Sequence Y] -> [Listof Y]
;; sort lst according to indicies in list inds
(define (sort2 ks ls)
(map second (sort (for/list ((k ks) (l ls)) (list k l)) < #:key
first)))
;;
------------------------------------------------------------------------
-----
;; Nat Nat -> [Listof Nat]
(define (range lo hi)
(if (>= hi lo)
(build-list (+ (- hi lo) 1) (lambda (i) (+ lo i)))
(build-list (+ (- lo hi) 1) (lambda (i) (- lo i)))))
(check-expect (encrypt "diesisteinklartext" 6) "dkinleiasertittxse")
(check-expect (decrypt "dkinleiasertittxse" 6) "diesisteinklartext")
(check-expect (decrypt (encrypt "diesisteinklartext" 6) 6)
"diesisteinklartext")
(check-expect (wave "diesisteinklartext" 6) (string->list
"dkinleiasertittxse"))
(check-expect (sort2 '(1 3 2) '(a b c)) '(a c b))
(test)