0

我怎样才能创建一个函数来懒惰地为字符'_'和'*'进行排列,如下所示:

例如:

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

第一个元素仅由 组成_,接下来的 3 个是列出的排列:*__,第二个 3 是列出的排列,**_最后一个元素仅包含*

我怎样才能做到这一点?

4

4 回答 4

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))
于 2012-06-29T22:41:41.657 回答
4

你可能想看看replicateM.

于 2012-06-30T00:09:04.690 回答
0
let k = ["_", "*"]
let p = [ a ++ b ++ c | a <- k, b <- k, c <- k ]
于 2012-06-29T21:46:03.683 回答
0

“正确顺序”版本:

import Data.List

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

不过,我不知道如何在恒定时间内从一种排列过渡到另一种排列。

于 2012-06-29T22:23:08.027 回答