在序列中找到第n代1/1 1/2 1/2 1 1 1

时间:2017-11-05 14:05:31

标签: haskell

我正在尝试构建一个Haskell程序,正如标题所说的那样。基本上每个单元格对应于之前的单元格,第二个单元格意味着前一个单元格中只有一个“1”,第三个单元格暗示前一个单元格中有两个“1”,依此类推。

我对haskell和它的语法都很新,所以我收到的大量错误都没有用,所以我正在使用这个论坛来帮助它。

这是我的代码:

findGen :: a -> a
findGen(x) = (getList (x))!!x

getList :: a -> [a]
getList (0) = []
getList (1) = [1]
getList (x) = getList(x-1) : ys where 
                            y = Ord getList(x-1) 
                            zs = group y
                            ds = countify(zs)
                            ys = concat(ds)

group :: Eq a => [a] -> [[a]]
group [] = []
group (x:xs) = (x:ys) : group zs where (ys,zs) = span ((==) x )xs


countify :: [a] -> [a]
countify(x:xs) = (y:xs) where y = count(x)

我想要做的是这样的: FindGen只是一个返回序列中第n个元素的函数。 getList是构建序列的函数,我试图使用Ord创建它到之前的列表,所以我可以对它进行分组,然后使用count来计算每个数字使用countify出现的次数,然后查找列表使其成为一个串。 试图找出我错在哪里,可能是在语法中,因为我觉得这个想法很好。

由于

3 个答案:

答案 0 :(得分:1)

我将提供一个不同的想法。请考虑以下列表,

  1. 有种子"1"
  2. 要扩展列表,您只需要依赖前一个元素。
  3. 因此,回顾1个元素是一个固定点,可以通过指定基本情况和归纳情况来实现,然后将它们连接起来。

    它导致两个衬垫。

    import Data.List (group, sort)
    
    genList :: [String]
    genList = "1" : map grow genList
      where grow s = (group $ reverse $ sort s) >>= (\n@(h:_) -> show (length n) ++ [h])
    
    main :: IO ()
    main = putStrLn $ show $ take 13 genList
    

    希望这是正确的,

    ["1","11","21","1211","1231","131221","132231","232221","134211","14131231","14231241","24132231","14233221"]
    

答案 1 :(得分:0)

  

我试图使用Ord

创建它

如果要对列表进行排序,请使用sort(如果我没记错的话,来自Data.List)

另请注意,由于您提供的类型签名错误,编译器将不接受getList。使用Integer代替a即可。以相同的方式修复findGen的签名。或者更好的是,在您更熟悉类型系统之前,不要给出类型签名。

此外,count是什么?为什么需要重新实施group

答案 2 :(得分:0)

如果我的图案正确,您可以使用Data.Map并使用iterate中的Data.List以懒惰的方式执行此操作,如下所示; (感谢@ luqui在地图方面的简化)

import qualified Data.Map.Lazy as M
makeMap :: String -> M.Map Char Int
makeMap cs = foldr incrementOr1 M.empty cs
             where 
             incrementOr1 c m | M.member c m = M.alter (fmap (+1)) c m
                              | otherwise    = M.insert c 1 m
makeMap :: String -> M.Map Char Int
makeMap = M.fromListWith (+) . map (flip (,) 1)

generateList :: [String]
generateList = iterate getChrCnt "1"
               where
               getChrCnt = M.foldrWithKey (\k n a -> a ++ show n ++ [k]) "" . makeMap

*Main> take 13 $ generateList
["1","11","21","1211","1231","131221","132231","232221","134211","14131231","14231241","24132231","14233221"]

有趣的是,它并没有超出第13次迭代的任何地方,结果是#34; 14233221"。刚收敛。