制限付き整数パーティション


8

P k(n)は、n正確にk部分に分割される量を意味します。とを与えnk、P k(n)を計算します。

ヒント:P k(n)= P k(n−k)+ P k−1(n−1)、n≤0またはkの場合、初期値p 0(0)= 1およびp k(n)= 0 ≤0。[Wiki]

n    k    Ans
1    1    1
2    2    1
4    2    2
6    2    3
10   3    8

ルール


1
タグ付けされていても、これがcode-golfであることを明確に示す必要があります
Xcoder氏2017

2
誰かがこのためにOEISにリンクできますか(CnR OEISポストで実行していたパーティションシーケンスの数が1つあると思います)
Stephen

3
最後のテストケースは8である必要があると思います
H.PWiz

2
最後のテストケースはの8代わりにすべきであるというH.PWizに同意し7ます。
Erik the Outgolfer 2017

回答:



3

Swift76 73バイト

func P(_ n:Int,_ k:Int)->Int{return n*k>0 ?P(n-k,k)+P(n-1,k-1):n==k ?1:0}

オンラインでお試しください!


説明

コードはどのように構造的に機能しますか?

まず、P2つの整数パラメーターnとを使用して関数を定義し、次のコード部分を使用しkて戻り型を指定します。ここでのクールなトリックは、パラメーターの名前を無視するようにコンパイラーに指示し、その後にスペースを続けることです。これにより、関数を呼び出すときに2バイト節約されます。明らかに、以下で説明するネストされた三項の結果を返すために使用されます。Intfunc P(_ n:Int,_ k:Int)->Int{...}_return

私が使用したもう1つのトリックはn*k>0、数バイトを節約することでしたn>0&&k>0。条件は(整数の両方がまだ高いよりも真である場合0)、その後、我々は再帰的に私たちの関数を呼び出すnだけ減少kなど私たちの新しいnk滞在同じ、と私たちはその結果を追加するP()nし、k条件が真でない場合は1ずつ減少します、1また0はがにn等しいかどうかに応じて、どちらかを返しますk

再帰アルゴリズムはどのように機能しますか?

シーケンスの最初の要素がp 0(0)であることを知っているので、両方の整数が正(n*k>0)であることを確認します。それらが0以下の場合、それらが等しい(n==l ?1:0)かどうかをチェックします。

  • 可能なパーティションは1つだけなので、整数が等しい場合は1を返します。

  • それらの一方がすでに0であり、もう一方が0でない場合、パーティションはありません。

両方が正である場合は、我々は再帰呼び出しPの結果を加算し、二回P(n-k,k)P(n-1,k-1)。そして、nが0になるまでループします。


* 注:スペースは削除できません。



2

パイソン261の 55 51 50バイト

Erik the Outgolferのおかげで-10バイト。Xcoder氏のおかげで-1バイト。

私は言うでしょう、私はヒントをOPからコピーしてPythonに翻訳しました。:P

P=lambda n,k:n*k>0and P(n-k,k)+P(n-1,k-1)or+(n==k)

オンラインでお試しください!


1
これは、
10、3

1
(n>0and k>0)->n>0<k
Erik the Outgolfer 2017

1
また、+(n==k)代わりに行うことができます[0,1][n==k]
Erik the Outgolfer 2017

1
のスペースは必要ありませんor +
Erik the Outgolfer 2017

1
50のバイトは、交換するn>0<k andn*k>0and
ミスターXcoder

2

Mathematica、33バイト

Length@IntegerPartitions[#,{#2}]&

ここにnxkテーブルがあります

 \k->
 n1  0  0   0   0   0   0   0   0   0  
 |1  1  0   0   0   0   0   0   0   0  
 v1  1  1   0   0   0   0   0   0   0  
  1  2  1   1   0   0   0   0   0   0  
  1  2  2   1   1   0   0   0   0   0  
  1  3  3   2   1   1   0   0   0   0  
  1  3  4   3   2   1   1   0   0   0  
  1  4  5   5   3   2   1   1   0   0  
  1  4  7   6   5   3   2   1   1   0  
  1  5  8   9   7   5   3   2   1   1  

1
もちろん。ビルトインがあることは知っていました。
Matthew Roh

A Mathematicaの簡体字のポートは、私は(信じてここに13のバイトを救うLength> - Len`1IntegerPartitions- >Int`7
ジョナサン・アラン・

@JonathanAllan私は実際にこれの超短いバージョンを作っています。うまくいけば、私は月末までにそれを終えることができます
JungHwan Min

2

JavaScript(ES6)、42 40 39バイト

これはうまくいくと思います。

f=(x,y)=>x*y>0?f(x-y,y)+f(--x,--y):x==y

それを試してみてください

k.value=(
f=(x,y)=>x*y>0?f(x-y,y)+f(--x,--y):x==y
)(i.value=10,j.value=3)
onchange=_=>k.value=f(+i.value,+j.value)
*{font-family:sans-serif}input{margin:0 5px 0 0;width:100px;}#j,#k{width:50px;}
<label for=i>n: </label><input id=i type=number><label for=j>k: </label><input id=j type=number><label for=k>P<sub>k</sub>(n): </label><input id=k readonly>


2

MATL、14バイト

y:Z^!S!Xu!Xs=s

オンラインでお試しください!

説明

入力を考えてみましょう62

y     % Implicitly take the two inputs. Duplicate from below
      % STACK: 6, 2, 6
:     % Range
      % STACK: 6, 2, [1 2 3 4 5 6]
Z^    % Cartesian power
      % STACK: 6, [1 1; 1 2; ... 1 5; 1 6; 2 1; 2 2; ...; 6 6]
!S!   % Sort each row
      % STACK: 6, [1 1; 1 2; ... 1 5; 1 6; 1 2; 2 2; ...; 6 6]
Xu    % Unique rows
      % STACK: 6, [1 1; 1 2; ... 1 5; 1 6; 2 2; ...; 6 6]
!Xs   % Sum of each row, as a row vector
      % STACK: 6, [2 3 ... 6 7 4 ... 12]
=     % Equals, element-wise
      % STACK: [0 0 ... 1  0 0 ... 0]
s     % Sum. Implicitly display
      % STACK: 3

正直なところ、MATLに「整数パーティション」が組み込まれていないことに驚いています。
Erik the Outgolfer 2017

@Sanchisesこれで動作するはずです。教えてくれてありがとう!
Luis Mendo 2017

問題ない。エラーに遭遇したとき、私はあなたの方法を理解するためにそれをいじっていただけです(これは一般的に小さな場合には簡単です)。
Sanchises




0

ゼリー、13 バイト

この基本的なアプローチ最もゴルフになることはない感じます!

RŒṖL€€Ṣ€QṀ€=S

オンラインでお試しください!


そうではありません(一番下のゼリーの答えを参照してください)。
Erik the Outgolfer 2017

ああ、コードボウリング
Matthew Roh

@EriktheOutgolfer機能する場合、なぜ削除されるのですか?
ジョナサンアラン

@ジョナサンの更新
マシュー・ロー

@JonathanAllanテストケースが修正される前に削除されました。
Erik the Outgolfer 2017



0

Scala、73バイト

さて、これはOPのヒントを簡単にやり直した使い方です。

knは私の再帰関数のパラメータですf。コンテキストについては、TIOリンクを参照してください。

これは再帰的なので、バイト数に関数defを含める必要がありますか?

(k,n)match{case(0,0)=>1
case _ if k<1|n<1=>0
case _=>f(n-k,k)+f(n-1,k-1)}

オンラインでお試しください!



0

R(+ pryr)、49バイト

f=pryr::f(`if`(k<1|n<1,!n+k,f(n-k,k)+f(n-1,k-1)))

再帰関数として評価されます

function (k, n) 
if (k < 1 | n < 1) !n + k else f(n - k, k) + f(n - 1, k - 1)

(k < 1 | n < 1)初期状態のいずれかが満たされているかどうかを確認します。との!n + k両方が0の場合はTRUE(1)、それ以外の場合はFALSE(0)と評価されます。再帰を処理します。nkf(n - k, k) + f(n - 1, k - 1)

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