对于一个Lisp课程,我们被分配了一个简单的行置换密码作业,我也尝试用Haskell解决它。基本上,只需将字符串分成长度为
以下是我的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
它完成了工作,但我不确定它是否被认为是惯用的 Haskell,因为我的索引调整感觉不太声明式。这个能否改进?如果可以,怎么做?
顺便问一下:Haskell 98 中是否有类似于 insertAt
的东西?也就是说,是否有一个函数将元素或列表插入到给定索引的列表中。
注意:这不是作业的一部分,而且作业今天已经截止。
idxs = [n*rows-1,(n-1)*rows-1..(filled+1)*rows-1]
。 - HaskellElephant