Для класса 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
Он выполняет свою работу, но я не уверен, будет ли это считаться идиоматическим Хаскеллом, так как моя игра с индексами не кажется слишком декларативной.Можно ли это улучшить, и если да, то как?
Кстати: есть ли что-то похожее на insertAt
в Haskell 98?Т.е. функция, вставляющая элемент или список по заданному индексу в список.
Примечание. Это НЕ часть домашней работы, которая должна была быть выполнена сегодня.