Lispクラスの場合、Haskellでも解決しようとした単純な行転置暗号の宿題が与えられました。基本的には、文字列を長さの行に分割しn
、結果を転置するだけです。結果として得られるcharのリストのリストの連結は、暗号化された文字列です。入力の最後の行(結果の不完全な列)に欠落している要素がある可能性があるため、デコードは少し難しくなります。これらの要素は処理する必要があります。
これは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と見なされるかどうかはわかりません。なぜなら、インデックスをいじるのはあまり宣言的ではないと感じているからです。これは改善できますか?もしそうなら、どのように?
ちなみに、Haskell98に似たものはありinsertAt
ますか?つまり、特定のインデックスにある要素またはリストをリストに挿入する関数です。
注:これは宿題の一部ではありません。とにかく今日の予定でした。