次のように、文字「_」と「*」の順列を遅延して作成する関数を作成するにはどうすればよいですか。
例えば:
Main> function 3
["___","*__","_*_","__*","**_","_**","*_*","***"]
最初の要素は のみから作成され_
、次の 3 つは をリストする順列で*__
あり、2 番目の 3 つは をリストする順列で**_
あり、最後の要素には のみが含まれます*
。
どうやってやるの?
次のように、文字「_」と「*」の順列を遅延して作成する関数を作成するにはどうすればよいですか。
例えば:
Main> function 3
["___","*__","_*_","__*","**_","_**","*_*","***"]
最初の要素は のみから作成され_
、次の 3 つは をリストする順列で*__
あり、2 番目の 3 つは をリストする順列で**_
あり、最後の要素には のみが含まれます*
。
どうやってやるの?
をご覧になることをお勧めしますreplicateM
。
別の「正しい順序」バージョンを次に示します。
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))
let k = ["_", "*"]
let p = [ a ++ b ++ c | a <- k, b <- k, c <- k ]
「正しい順序」バージョン:
import Data.List
function k = concatMap (nub . permutations . pat) [0..k]
where pat x = replicate x '*' ++ replicate (k-x) '_'
ただし、ある順列から別の順列に一定時間でステップする方法はわかりません。