Простой шифр транспонирования строк

Для класса Lisp, нам дали простое домашнее задание по транспонированию строк, которое я тоже пытался решить на Haskell. По сути, можно просто разбить строку на строки длиной n , а затем транспонировать результат. Объединение результирующего списка списков символов представляет собой зашифрованную строку. Декодирование немного сложнее, поскольку в последней строке ввода могут отсутствовать элементы (неполные столбцы в результате), о которых необходимо позаботиться.

Это мое решение на Haskell:

import Data.List
import Data.Ratio
import Data.List.Split

encode :: String -> Int -> String
encode s n = concat . transpose $ chunk n s

decode :: String -> Int -> String
decode s n = take len $ encode s' rows
    where s'     = foldr (insertAt " ") s idxs
          rows   = ceiling (len % n)
          idxs   = take (n-filled) [n*rows-1,(n-1)*rows-1..]
          filled = len - n * (rows - 1)
          len    = length s

insertAt :: [a] -> Int -> [a] -> [a]
insertAt xs i ys = pre ++ xs ++ post
    where (pre,post) = splitAt i ys

Оно выполняет job, но я не уверен, будет ли это считаться идиоматическим Haskell, так как моя игра с индексами не кажется слишком декларативной. Можно ли это улучшить, и если да, то как?

Кстати: есть ли что-нибудь похожее на insertAt в Haskell 98? Т.е. функция, вставляющая элемент или список по заданному индексу в список.

Примечание. Это НЕ часть домашнего задания, которое в любом случае должно было быть выполнено сегодня.

8
задан skaffman 20 December 2010 в 20:18
поделиться