代码之家  ›  专栏  ›  技术社区  ›  AdamK

编写代码以反转Haskell程序

  •  1
  • AdamK  · 技术社区  · 7 年前

    我编写了一个程序,将消息作为字符串,并根据需要用X填充消息,以返回一个字谜,这样字符串长度正好有4个因子,然后基本上重新排列消息,就像它是在网格中组织的一样,并向下读取而不是交叉读取。例如,输入“Haskell”将返回字符串“HealslkX”。我已经编写了一个程序来编码这个字谜,但我在编写一个程序来反转之前的程序并解码字谜时遇到了麻烦,尤其是使用removeX函数时,它应该删除X填充。以下是我所拥有的:

    import Data.List
    
    factors :: Int -> [Int]
    factors n = [x | x <- [1..n], n `mod` x == 0]
    
    split :: Int -> [a] -> [[a]]
    split _ [] = []
    split n xs =
        let (ys, zs) = splitAt n xs
        in  ys : split n zs
    
    encode :: [Char] -> [Char]
    encode (x:xs) = if (length (factors (length xs))) == 4 then concat 
    (transpose (split ((factors (length xs))!!2) xs))
    else encode (xs ++ ['X'])
    

    解码:

    import Data.List
    
    factors :: Int -> [Int]
    factors n = [x | x <- [1..n], n `mod` x == 0]
    
    split :: Int -> [a] -> [[a]]
    split _ [] = []
    split n xs =
        let (ys, zs) = splitAt n xs
        in  ys : split n zs
    
    removeX :: [a] -> [a]
    removeX xs = if (last xs) == 'X' then ((init xs) && removeX xs)
     else xs
    
    decode :: [Char] -> [Char]
    decode (x:xs) = removeX (concat (transpose (split ((factors (length xs))!!1) xs)))
    
    1 回复  |  直到 7 年前
        1
  •  3
  •   Daniel Wagner    7 年前

    只需使用 removeX (init xs) 而不是 init xs && removeX xs

    同时考虑 removeX = reverse . dropWhile ('X'==) . reverse