2012-06-29 78 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我不想把它完全拼出來,因爲實際的完整答案已經被刪除。 –