Haskell中有趣的谜题

时间:2014-03-13 20:12:25

标签: haskell

你好学习Haskell我在网上练习,它要求创建一个给定整数的列表,如下所述:

例如,如果integer为3,则应生成包含以下内容的列表:

[[3],[1,2],[2,1],[1,1,1]]

注意

3=3
1+2=3
2+1=3
1+1+1=3

如果整数是2那么它将是:

[[2],[1,1]]

我无法想到实现这一点的方法,所以你能给我提供任何提示吗?我相信我必须使用列表理解,但我想不出比这更进一步的

2 个答案:

答案 0 :(得分:10)

始终以类型签名开头:

sums :: Int -> [[Int]]

现在,让我们考虑一下递归。

  1. 什么是基本情况?你能想到一个答案很简单的数字吗?
  2. 我们假设您已经实现了您的功能,它适用于10以下的所有数字,因此sums 9会返回正确的答案。您将如何实施sums 10
  3. 在您回答这些问题之前,请不要为实施细节(例如列表理解与filtermap)烦恼。

    另一个提示:Haskell程序员喜欢炫耀并创建微小的免费功能,但不要让它混淆你。让事情发挥作用是重要的。有一个工作但有点"丑陋"更好。解决方案,而不是盯着屏幕寻找一个优雅的。

    祝你好运!

答案 1 :(得分:2)

看起来有点像分区列表。一点谷歌搜索出现了

http://www.haskell.org/pipermail/beginners/2011-April/006832.html

partitions [] = [[]]
partitions (x:xs) = [[x]:p | p <- partitions xs]
                 ++ [(x:ys):yss | (ys:yss) <- partitions xs]

产生类似这样的东西

*Main> partitions "abc"
[["a","b","c"],["a","bc"],["ab","c"],["abc"]]

现在您所要做的就是获取内部列表的长度

map (map length) (partitions "abc")
[[1,1,1],[1,2],[2,1],[3]]

您也可以更改分区直接为您提供结果

partitions' 0 = [[]]
partitions' n = [1:p | p <- partitions' (n-1)]
             ++ [(1+ys):yss | (ys:yss) <- partitions' (n-1)]