2012-06-29 42 views
0

如何创建一个函数,它懒洋洋地使排列的字符“_”和“*”这样的:哈斯克尔 - 如何生成排列

例如:

Main> function 3 
["___","*__","_*_","__*","**_","_**","*_*","***"] 

第一个元素是由仅从_开始,接下来的3个列表是:*__,第二个3列出了**_,最后一个元素仅包含*

我该怎么做?

+2

这功课吗?你有什么尝试? – is7s

+1

这不应该被称为“排列” – newacct

+1

@ rotskoff:排列意味着您可以订购3个球的方式的数量。 3个球的排列数是6.你所问的是完全不相关的。你并不总是选择3 *(有时你选择0,1或2)。而且你也没有区分不同的*(这意味着没有秩序;这是排列的本质)。 – newacct

回答

0
let k = ["_", "*"] 
let p = [ a ++ b ++ c | a <- k, b <- k, c <- k ] 
+0

这将以错误的顺序生成列表。 – dave4420

+0

我想过任何数字的松散函数。但我发现类似的东西 replicateM 3“_ *” 但是首先你必须输入Control.Monad – Simon

+0

@SzymonSkrzyński由于'replicateMķfoo'是'序列$重复ķfoo',你可以做,没有导入' Control.Monad'。这些积木可以从“Prelude”中找到。但是如果这对你很重要,那并不能达到所需的顺序。 –

0

“正确顺序”的版本:

import Data.List 

function k = concatMap (nub . permutations . pat) [0..k] 
    where pat x = replicate x '*' ++ replicate (k-x) '_' 

我不知道如何从一个置换步骤到另一个在固定时间内,虽然。

4

这里还有一个 “正确的顺序” 的版本:

function :: Int -> [String] 
function c = concatMap helper $ zip (reverse [0..c]) [0..c] 

helper :: (Int, Int) -> [String] 
helper (c,   0)   = [replicate c '_'] 
helper (0,   c)   = [replicate c '*'] 
helper (cUnderscores, cAsterisks) = map ('_' :) (helper (cUnderscores - 1, cAsterisks)) 
           ++ map ('*' :) (helper (cUnderscores, cAsterisks - 1)) 
4

你可能想看看replicateM

+2

虽然正确,但这并不是很有帮助,甚至作为一个提示。大多数人不会得到这个把戏,除非你第一次为他们拼出来。至少要提到它需要特定的monad列表。 –

+0

@GabrielGonzalez我不想把它完全拼出来,因为实际的完整答案已经被删除。 –