可能なすべての一意の n タプルを取得したい x 要素のリストがあります。
だから私は基本的にの実装を探しています
nub . map (take n) . permutations
不必要に重複を作成しません。
私にとって、これはすでにどこかで定義されている可能性が高い関数のように見えます。
これは事実ですか?
可能なすべての一意の n タプルを取得したい x 要素のリストがあります。
だから私は基本的にの実装を探しています
nub . map (take n) . permutations
不必要に重複を作成しません。
私にとって、これはすでにどこかで定義されている可能性が高い関数のように見えます。
これは事実ですか?
このようなことを意味しますか?
import Data.List (permutations)
choose n list = concatMap permutations $ choose' list [] where
choose' [] r = if length r == n then [r] else []
choose' (x:xs) r | length r == n = [r]
| otherwise = choose' xs (x:r)
++ choose' xs r
出力:
*Main> choose 2 [0..5]
[[1,0],[0,1],[2,0],[0,2],[3,0],[0,3],[4,0],[0,4],[5,0],[0,5],[2,1]
,[1,2],[3,1],[1,3],[4,1],[1,4],[5,1],[1,5],[3,2],[2,3],[4,2],[2,4]
,[5,2],[2,5],[4,3],[3,4],[5,3],[3,5],[5,4],[4,5]]
タプルを要求したので、リストが適用可能なファンクターであるという事実を利用したソリューションを次に示します。
Prelude> let list = [0..4]
Prelude> import Control.Applicative
Prelude Control.Applicative> (,) <$> list <*> list
[(0,0),(0,1),(0,2),(0,3),(0,4),(1,0),(1,1),(1,2),...
Prelude Control.Applicative> (,,) <$> list <*> list <*> list
[(0,0,0),(0,0,1),(0,0,2),(0,0,3),(0,0,4),(0,1,0),(0,1,1),...
n
ただし、異なるアリティのタプルは定義上異なる型であるため、何らかのパラメーターに基づいて異なるアリティの結果を生成するユニバーサル関数を作成することは不可能です。
これは、サポートしたいタプルのアリティを表すタイプレベルのナチュラルのタイプクラスとインスタンスを導入することにより、いくつかの高度なタイプレベルのプログラミング手法を使用して解決できることに注意する必要がありますが、これはやり過ぎになると確信しています. さらに、必要なすべての情報が結果の型から決定される可能性があるため、自然型を使用することも冗長になります。そのため、サポートするすべてのタプルの単純な型クラスとインスタンスで十分です。
Hayoo は、関数を見つけるのに非常に役立ちます。このクエリで、私はpermutationパッケージを見つけました。これは、実装を詳細に調べていませんが、あなたが望むことをするかもしれません。
ただし、Stack Overflow で説明されているソリューションのいずれかを使用する方が簡単な場合があります。検索すると、関連する投稿がいくつか見つかりました。Data.List での関数の実装に関するこの説明を見て、必要に応じて変更してください。permutations
Math.Combinatorics.Multiset
( )を使用できますcabal install multiset-comb
。これにより、入力リストに重複がある場合でも、出力リストで重複が回避されます。
import Math.Combinatorics.Multiset (fromList, kSubsets, permutations)
permute :: Ord a => Int -> [a] -> [[a]]
permute n = concatMap permutations . kSubsets n . fromList
main = print $ permute 2 [1, 1, 2, 3]
プロデュース:
[[2,3],[3,2],[1,3],[3,1],[1,2],[2,1],[1,1]]