置換を伴う組み合わせを生成する


10

n個の要素のセットから、サイズkの置換(または繰り返しの組み合わせ)のあるすべての組み合わせをリストします。

置換との組み合わせは、その中のすべての要素がn個の要素のセットにも含まれる、順序付けされていないマルチセットです。ご了承ください:

  • 順不同です。したがって、異なる順序で以前に印刷されたセットは、再度印刷されません。
  • マルチセットです。同じ要素を複数回表示できます(必須ではありません)。これは、交換との組み合わせと通常の組み合わせの唯一の違いです。
  • セットは正確にk個の要素を持つ必要があります。

代わりに、それはn個の要素のそれぞれをk回含むマルチセットのサイズkのサブセットでもあります。

入力がなければならないのいずれかのn及びkの要素が最初であり、nは正または負でない整数、またはn個の要素及びKあなたが引き受けることができる、n個の要素は、互いに全て異なっています。

出力は、指定されたセットのサイズkで置き換えられたすべての組み合わせのリストである必要があります。それらと各要素の要素を任意の順序で印刷できます。

置換を伴う組み合わせを生成するビルトインは使用できません。しかし、組み込みを使用して、通常の組み合わせ、順列、タプルなどを生成できます。

これはコードゴルフで、最短のコードが勝ちます。

Input: 4 2
Output: [0 0] [0 1] [0 2] [0 3] [1 1] [1 2] [1 3] [2 2] [2 3] [3 3]

回答:



8

CJam(8バイト)

{m*:$_&}

オンラインデモ

解剖

{    e# Declare block (anonymous function); parameters are n k
  m* e# Cartesian product, which implicitly lifts n to [0 1 ... n-1]
  :$ e# Sort each element of the Cartesian product, to give them canonical forms
  _& e# Deduplicate
}

3

Mathematica、31 29バイト

2バイトを節約してくれたA Simmonsに感謝します。

{}⋃Sort/@Range@#~Tuples~#2&

無名の機能取っnおよびk整数引数としてそのために、そしてリストのリストを返します。要素になります1n。ピーターのCJam回答と同じように機能します。


@ jimmy23013私が知らない人。
マーティンエンダー

2バイトを節約できると思います{}∪Sort/@Range@#~Tuples~#2&
Simmons

@ASimmonsいいアイデア、ありがとう!
マーティンエンダー

3

MATL、11バイト

(デカルトのパワーに基づいた9バイトのソリューションがありますが、ピーターテイラーはすでにそれを実行しています。別の方法を試してみましょう)。

置換ありの組み合わせは、以下のように置換なしの組み合わせに減らすことができます。我々はしたいn Cr kと、たとえば、n=3k=2

0 0
0 1
0 2
1 1
1 2
2 2

計算できますn+k-1 C k

0 1
0 2
0 3
1 2
1 3
2 3

次に0 1 ... k-1、各行から減算します。

+q:2GXn2G:-

説明:

+q     % take two inputs n, k and compute n+k-1
:      % range [1,2...,n+k-1]
2G     % push second input, k
Xn     % combinations without replacement
2G:    % range [1,2,...,k]
-      % subtract with broadcast. Display

コードは言語/コンパイラのリリース13.1.0で動作しますが、これはチャレンジよりも前の段階です。

あなたはそれをオンラインで試すことができます!オンラインコンパイラはリリース14.0.0に更新されているためXn、に変更する必要があることに注意してくださいXN


3

JavaScript(Firefox 30-57)、71バイト

f=(n,k)=>k?[for(m of Array(n).keys())for(a of f(m+1,k-1))[...a,m]]:[[]]

keys()回使用できます。


2

Ruby、56 55バイト

驚くべきことに、長さが同じ2つのソリューション:

->n,k{[*1..n].repeated_permutation(k).map(&:sort).uniq}
->n,k{(a=[*1..n]).product(*[a]*(k-1)).map(&:sort).uniq}

ねえ、あなた私たちが順列ビルトインを使うことができると言いました...

これは単にすべての繰り返される順列を生成し(2番目の順列は繰り返されるデカルト積を生成します)、並べ替えられていないものを削除します。

0...n-> 1..n!でバイトを保存してくれたMartinに感謝します。


1

Pyth、7バイト

{SM^UQE

ピーターの答えと同じアルゴリズムを使用します。

    UQ   range(input())
      E  input()
   ^     repeated Cartesian product of ^^, ^ times
 SM      map(sort)
{        uniq

1

Python、63バイト

f=lambda n,k:n*k and[l+[n]for l in f(n,k-1)]+f(n-1,k)or[[]][k:]

再帰的な方法。マルチセットにするためにk要素を、1するためにn、我々はどちらかに選択します。

  • 別のインスタンスを含めn、それがのマルチセットにするために残っているk-1から要素を1しますn
  • の別のインスタンスを含めないでください。これによりnk要素のマルチセットが1to からtoになります。n-1

私たちは、終了時にいずれかkまたはn達し0、それがあればk到達し0、我々は空のリストのベースケースを与えます。そうでない場合は、要素の数が間違っているため、空のリストを指定します。


1

Python 3、81 80

再帰的な解決策:

t=lambda n,k,b=0:[[]]if k<=0 else [[i]+l for i in range(b,n)for l in t(n,k-1,i)]

この関数t(n, k, b)は、〜kの範囲のすべての要素の複数サブセットのリストを返します。の場合、このリストは空です。それ以外の場合は、マルチサブセットの最小要素に基づいて問題を分解します。これをで示します。bnk <= 0i

それぞれについてiの範囲内bn、我々は、すべての生成k最小要素と-マルチ・サブセットをi用いて開始することによって[i]、次いで、各追加(k-1)の範囲の-マルチ・サブセットin、我々は再帰的に呼び出すことによって得ました、t(n, k-1, i)


プログラミングパズルとコードゴルフへようこそ!これは良い最初の答えです。コードがどのように機能するかについての説明を提供できますか?
Alex A.

素晴らしく見える。素敵な解決策!
Alex A.

1

Dyalog APL、22バイト

{∪{⍵[⍋⍵]}¨↓⍉⍺⊥⍣¯1⍳⍺*⍵}

が必要⎕IO←0です。これは、多くのAPLシステムのデフォルトです。左の引数としてk、右の引数としてnを取ります。

⍳⍺*⍵0 1 2 ...kⁿkに
⍺⊥⍣¯1変換k
転置
行列をリストのリストにして、
{⍵[⍋⍵]}¨それぞれをソートします...
一意


1

J、18バイト

[:~.#~<@/:~@#:i.@^

@Adámのソリューションで使用される同様のアプローチ。

{24バイトのデカルト積を使用する別のアプローチ。受け取りkLHS上とnRHSに。

~.@:(/:~&.>)@,@{@(#<@i.)

使用法

   f =: [:~.#~<@/:~@#:i.@^
   4 f 2
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│0 0│0 1│0 2│0 3│1 1│1 2│1 3│2 2│2 3│3 3│
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘

説明

[:~.#~<@/:~@#:i.@^ Input: n on LHS and k on RHS
                 ^ Compute n^k
              i.@  Create a range [0, 1, ... n^k-1]
    #~             Create k copies on n
            #:     On each value in the range above, convert each digit to base-n
                   and take the last k digits of it
        /:~@       For each array of digits, sort it in ascending order
      <@           Box each array of digits
[:~.               Take the distinct values in the array of boxes and return it

1

Clojure、94バイト

(defn f[k n](if(= 1 k)(for[i(range n)][i])(sort(set(for[i(f(dec k)n)j(range n)](conj i j))))))

変更されたパラメーターの順序に注意してください。1番目がkで2番目がnです。これにより、1バイトが節約されました(f(dec k)n)


0

Mathematica、36バイト

{##}&~Array~Table@##~Flatten~(#2-1)&

[] sを使用しない場合の1/6ボーナスがあることを教えてください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.