cypher function :: [(Int,Char)] - > [串]

时间:2013-02-03 21:02:32

标签: haskell

我想要一个带签名的函数:: [(Int,Char)] - > [String]取每个Char并根据相应对中的Integer值将它们组合成一个Strings列表...

[(0,'A'),(1,'B'),(2,'C'),(3,'D'),(0,'E'),(1,'F'),(2,'G'),(3,'H'),(0,'I'),(1,'J'),(2,'K'),(3,'L'),(0,'M'),(1,'N'),(2,'O'),(3,'P')]

应该生成列表:[“MIEA”,“NJFB”,“OKGC”,“PLHD”]

我试过了:

toList :: [(Int,Char)] -> Int -> [String]
toList [] a = []
toList (x:xs) a = [snd(x) | n <-[0..(a-1)], fst(x) == n]:toList xs a

但这只是给了我:

["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P"]

任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:3)

您需要按索引对输入进行排序,然后使用相同的索引对所有对进行分组。像下一个:

map (reverse . map snd) $ groupBy ((==) `on` fst) $ sortBy (compare `on` fst) $ input

没有$运算符:

import Data.List
import Data.Function

toList :: [(Int, Char)] -> [String]
toList input = map (reverse . map snd) grouped
  where
  sorted = sortBy (compare `on` fst) input    -- sorted by the index
  grouped = groupBy ((==) `on` fst) sorted    -- grouped by the index

答案 1 :(得分:1)

既然我的作业截止日期已过,我可以提出我的整个问题......要求函数将模拟的“图片”顺时针旋转90度。我提出的解决方案(使用简单的Haskell代码,因为这是我们的第一个任务)如下。虽然它为简单的“方形”字符串列表做了工作,但它似乎不适用于更多的矩形列表...不确定为什么。

{- The function rotate90 rotates a "picture" (List of Strings) through
   90 degrees clockwise and prints the list to the standard output device
   using the printPicture function defined in the Thompson Picture.hs file.
-}

-- the following String list is a sample used to test implementation:
pic :: [String]
pic = [ "ABCD", "EFGH", "IJKL", "MNOP", "QRST" ]

rotate90 :: [String] -> IO ()
rotate90 aPic   = printPicture(convertToPic (listPairs aPic (maxOfList(widthOfLines aPic))     ((maxOfList(widthOfLines aPic))*(length(aPic)))) ([0..((maxOfList(widthOfLines aPic))-1)]))

-- takes a picture, the width and the number of Chars in a rectangle
-- bounding the picture (area) and converts it to a list of pairs with
-- an address and Char as per the cypher algorithm:
-- address = floor of (area -1)/ width
listPairs :: [String] -> Int -> Int -> [(Int,Char)]
listPairs [] w area = []
listPairs aPic w area   = [ (((n-1)`mod`w),(aPic!!(floor(fromIntegral(n-1)/(fromIntegral(w))))!!((n-1)`mod`w))) | n <- [1..area] ]

-- takes a list of tuples (pairs) and an Int which is the width of the input picture
-- it retunrs a list of Strings that correspond to the groupings of the pairs.
convertToPic :: [(Int,Char)] -> [Int] -> [String]
convertToPic [] (y:ys)  = []
convertToPic somePair []    = []
convertToPic somePair (y:ys)= reverse([ snd(x) | x <- somePair, ((fst(x)) == y)]):(convertToPic somePair ys)

-- takes a list of Int and returns the maximum value from the list as an Int
maxOfList :: [Int] -> Int
maxOfList []        = 0
maxOfList (x:xs)        = max x (maxOfList xs)

-- takes a list of type String and returns a list of Int of the length of each string
widthOfLines :: [String] -> [Int]
widthOfLines []     = []
widthOfLines (x:xs)     = (length x):(widthOfLines xs)

-- definition from Thompson (textbook) picture.hs file
printPicture :: [String] -> IO ()
printPicture = putStr . concat . map (++"\n")