パーティションはいくつありますか?


16

正の整数のパーティション番号は、正の整数の合計として表現できるウェイの数として定義されます。言い換えれば、それが持っている整数パーティションの数。たとえば、番号4には次の部分があります。

[[1、1、1、1]、[1、1、2]、[1、3]、[2、2]、[4]]

したがって、5パーティションがあります。これはOEIS A000041です。


仕事

与えられた正の整数Nは、そのパーティション番号を決定します。

  • すべての標準ルールが適用されます。

  • 入力および出力は、合理的な手段で処理できます。

  • これはであるため、バイト単位の最短コードが優先されます。


テストケース

入力| 出力

1 | 1
2 | 2
3 | 3
4 | 5
5 | 7
6 | 11
7 | 15
8 | 22
9 | 30
10 | 42

1
私はこれが複製だとほぼ
確信してい

@DJMcMayhemうーん、わかりました。重複を見つけたら教えてください。申し訳ありませんが、私はこのすべてに新しいです!

1
@DJMcMayhem これは、「生成」から「カウント」への短いステップなので、あなたが尋ねたかもしれませんが、それらをカウントするためにすべてのパーティションを必ずしも生成する必要はありません...-
Giuseppe

1
これは、popcon(?)であり、広すぎるとして閉じられている以外は、だまされています。私見これはまさしく書かれており、開いたままにしておくべきですが、古いものは(再開して))として閉じられるべきです
ロッド

2
@Rod、それは悪いポップコンですが、近い理由をだましに切り替えても改善にはなりません。パフォーマンス要件により、いくつかの回答を移植するのに障害が生じます(数分で1000の24061467864032622473692149727991パーティションが生成されることはありません)。Hardy-Ramanujan-Rademacherの実装は正確にはゴルフではありません...しかし、この質問とその質問をどうするかについてメタで議論する価値があるかもしれません。
ピーターテイラー

回答:


13

Pyth、3バイト

l./

ここで試してみてください!またはテストスイートを試してください。

答えは、コード自体を書くよりもフォーマットするのにはるかに長い時間がかかりました:P。


どうやって?

Pythは仕事に最適なツールです。

l。/暗黙的な入力を伴う完全なプログラム。

 ./整数パーティション。入力に追加される正の整数のすべてのソート済みリストを返します。
l長さ。
      結果を暗黙的に出力します。


8

パイソン285の 83バイト

@notjaganのおかげで-2バイト

lambda n:n<1or sum(sum(i*((n-k)%i<1)for i in range(1,n+1))*p(k)for k in range(n))/n

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

OEIS A000041の再帰式を使用します。



84バイト。この場合==0と同等<1です。編集: notjaganのアプローチを使用する
氏Xcoder

@ Mr.Xcoder元のコードには実際に <1代わりににありました==0が、TIOコードにはありませんでした。
-notjagan

また、83バイト
氏Xcoder

8

Emojicode 0.5、204の 201バイト

🐋🚂🍇🐖🅰️➡🚂🍇🍊⬅🐕1🍇🍎1🍉🍮s 0🔂k⏩0🐕🍇🍦t➖🐕k🍮r t🔂i⏩1 t🍇🍊😛🚮t i 0🍇🍮➕r i🍉🍉🍮➕s✖r🅰️k🍉🍎➗s🐕🍉🍉

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

「未満」の絵文字はかなり長いUTF-8エンコーディングを使用しているため、「2未満」ではなく「1以下」を使用して-3バイト。またt、バイトカウントに影響を与えずに警告を黙らせるためにフローズンを作成しました。

🚂️という名前のメソッドで🚂(整数)クラスを拡張します。入力から数値を取得し、その数値に対して🅰️を呼び出し、次のように結果を出力する簡単なプログラムを作成できます。

🏁🍇
 🍦str🔷🔡😯🔤Please enter a number🔤
 🍊🍦num🚂str 10🍇
  😀🔡🅰️num 10
 🍉🍓🍇
  😀🔤Learn what a number is, you moron!🔤
 🍉
🍉

この部分は、メッセージとエラー処理を省略することで大いに楽しむことができますが、スコアには含まれていません。そのため、読みやすさを向上させながら、代わりに絵文字コードのより多くの機能を表示することを好みます。

非ゴルフ

🐋🚂🍇
 🐖🅰️➡🚂🍇
  🍊◀️🐕2🍇
   🍎1
  🍉
  🍮sum 0
  🔂k⏩0🐕🍇
   🍦nmk➖🐕k
   🍮sig nmk
   🔂i⏩1 nmk🍇
    🍊😛🚮nmk i 0🍇
     🍮➕sig i
    🍉
   🍉
   🍮➕sum✖sig🅰️k
  🍉
  🍎➗sum🐕
 🍉
🍉

説明

注: emojicode 0.5では、多くの絵文字を選択しても意味がありません。結局、0.xです。0.6はこれを修正します。

Emojicodeは、ジェネリック、プロトコル、オプション、およびクロージャーを備えたオブジェクト指向プログラミング言語ですが、このプログラムはクロージャーを使用せず、すべてのジェネリックとプロトコルは暗黙的と見なすことができますが、オプションはI / Oスタブにのみ表示されます。

プログラムはいくつかのタイプでのみ動作します:🚂は整数型、🔡は文字列型、⏩は範囲型です。いくつかのブール値(👌)も表示されますが、これらは条件でのみ使用されます。ブール値は、それぞれtrueとfalseに対応する👍または👎の値を取ることができます。

現在、Emojicodeには演算子はないため、通常は演算子である加算、比較、およびその他の操作は関数として実装され、効果的に式にプレフィックス表記を使用させます。オペレーターも0.6で計画されています。

最初にテストプログラムに取り組みましょう。

🏁

これは🏁ブロックであり、他の言語のmainと比較できます。

🍇 ... 🍉

ブドウとスイカは、絵文字コードでコードブロックを宣言します。

🍦str🔷🔡😯🔤Please enter a number🔤

これは、「凍結」という名前strを宣言し、その値を初期化子(コンストラクター)createdを使用して作成された新しい文字列に設定します。変数の代わりに凍結を使用するのはなぜですか?変更されないため、変数は警告を発します。

🍊🍦num🚂str 10

分解しましょう。手段で🚂str 10🚂メソッドを呼び出します:式を評価します。オプションに何も含まれていない場合、条件は👎(偽)と評価されます。それ以外の場合は、オプションのラップされていない値を使用して凍結された名前が作成され、条件は👍(true)に評価されます。したがって、通常の使用では、条件に続くブロックが入力されます。str引数10を frozenでます。慣例により、型の名前が付いたメソッドは、オブジェクトをその型に変換します。10は整数変換に使用するベースです。このメソッドは、オプションのを返します🍬🚂。オプションには、基本タイプまたは空の値⚡を含めることができます。文字列に数字が含まれていない場合、⚡が返されます。値を使用するには、optionalを使用してオプションをアンラップする必要があります。値がifの場合、ランタイムエラーが発生します。したがって、オプションをアンラップする前に、無をチェックすることをお勧めします。実際、Emojicodeにはそのための略記があります。通常、🍊「if」です。🍊🍦 variable expressionvariable🍇 ... 🍉

😀🔡🅰️num 10

🅰️は、パーティションの数を計算する🚂を使用してメインコードがtoに追加する方法です。これはnum、条件で宣言したフローズンで🅰️を呼び出し、resultメソッドによって基数10を使用して結果を文字列に変換します。次に、😀は結果を出力します。

🍓🍇 ... 🍉

は "else"を意味するため、ユーザーが数字を正しく入力しなかったときにこのブロックが入力されます。

😀🔤Learn what a number is, you moron!🔤

文字列リテラルを出力します。

それでは、メインプログラムを見てみましょう。未使用バージョンについて説明します。ゴルフバージョンでは、空白が削除され、変数の名前が1文字の名前に変更されました。

🐋🚂🍇 ... 🍉

🚂クラスを拡張します。これは、プログラミング言語では一般的に見られない機能です。classをスーパークラスとして新しいクラスを作成する代わりに、🐋は🚂を直接変更します。

🐖🅰️➡🚂🍇 ... 🍉

🚂を返す🅰️という名前の新しいメソッドを作成します。式を使用して計算されたパーティションの数を返しますa(n) = (1/n) * Sum_{k=0..n-1} sigma(n-k)*a(k)

🍊⬅🐕1🍇
 🍎1
🍉

は他の言語と類似thisまたはself他の言語からのもので、メソッドが呼び出されたオブジェクトを指します。この実装は再帰的であるため、これが終了条件です。メソッドが呼び出された数が1以下の場合、1を返します。

🍮sum 0

新しい変数sumを作成し、0に設定します。暗黙的に型assumesを想定しています。

🔂k⏩0🐕

は🔂🐚⚪️プロトコルを実装するものを繰り返し処理しますが、⏩はhappensを実装する範囲リテラルです。範囲には、開始値、停止値、およびステップ値があり、の場合start < stopは1 、そうでない場合は-1 と想定されます。⏭を使用して範囲リテラルを作成することにより、ステップ値を指定することもできます。開始値は包括的であり、停止値は排他的であるため、これは式for k in range(n)またはと同等Sum_{k=0..n-1}です。

🍦nmk➖🐕k

sigma(n-k)、またはn - k言い換えれば約数の合計を計算する必要があり、引数が数回必要になるため、これn - kは変数nmkに格納していくつかのバイトを節約します。

🍮sig nmk
🔂i⏩1 nmk

これにより、sig変数がsigmaの引数に設定され、1〜のすべての数値が反復処理されますnmk - 1。変数を0に初期化し、1..nmkを反復処理することもできますが、この方法を使用する方が短時間です。

🍊😛🚮nmk i 0

remainderは剰余またはモジュラスを計算し、😛が等しいかどうかをチェックするため、条件iはの除算であれば👍になりますnmk

🍮➕sig i

これは、+= -= >>=いくつかの劣った絵文字のない言語の演算子族に似た呼び出しによる割り当てです。この行は、と書くこともできます🍮 sig ➕ sig i。したがって、内側のループが終了sigすると、の約数の合計が含まれますn - k、またはsigma(n - k)

🍮➕sum✖sig🅰️k

呼び出しによる別の割り当て。これによりsigma(n - k) * A(k)、式のように合計に追加されます。

🍎➗sum🐕

最後に、合計がnで除算され、商が返されます。この説明は、おそらくコード自体を書くのと同じくらいの時間がかかりました...



3

オクターブ、18バイト

partcnt(input(''))

組み込み関数partcntを使用します。

@を使用する匿名関数を使用して正しく取得できない場合、いくつかの助けをいただければ幸いです。


3

網膜、34バイト

.+
$*
+%1`\B
;$'¶$`,
,

%O`1+
@`.+

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

説明

.+
$*

入力を単項に変換します。

+%1`\B
;$'¶$`,

これは、単項リストの2 n-1パーティションすべてを計算します。これを行うには、各行+の最初の(1)非単語境界(\B、つまり2つ1のsの間の位置)を繰り返し()一致させ、%それを;に置き換え、その後のすべて($')、改行()、それ($`)と,。例:

1;1,111

になる

      vv
1;1,1;11
1;1,1,11
^^^^^

どこ vマークの結果$'^結果をマーク$`。これは、2つの異なる置換の結果を一度に取得する一般的なイディオムです(基本的に;との両方を挿入し、,2つの完全な置換を完了するために文字列の欠落した「半分」を挿入します)。

扱います ;実際のパーティション,として、また後続のパーティションとの\Bマッチングを防ぐプレースホルダーとしてます。次は…

,

...これらのコンマを削除します。これですべてのパーティションができました。入力の例4

1;1;1;1
1;1;11
1;11;1
1;111
11;1;1
11;11
111;1
1111

ただし、順序は重要ではありません。

%O`1+

これにより、 1、各行 s並べられ、順序付けられていないパーティションが取得されます。

@`.+

最後に、の一意の(@)マッチ.+、つまり、取得した個別の行/パーティションの数をカウントします。私はこの@オプションを何年も前に追加しましたが、それを完全に忘れて、つい最近再発見しました。この場合、行の最初の重複排除で1バイトを節約しますD`


3

パイソン254の、53バイト

f=lambda n,k=1:1+sum(f(n-j,j)for j in range(k,n/2+1))

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

使い方

nの各パーティションは、x 1 +⋯+ x m = nのようなリストx = [x 1、⋯、x m ]として表すことができます。我々はそれが必要な場合、この表現はユニークとなり、X 1 ≤⋯≤X メートルを

我々は、補助関数定義F(n、k)は下限とパーティションをカウントkは、リスト、すなわち、xはそのようなことは、X 1 +⋯+ X M = NK≤X 1 ≤⋯≤X M。したがって、入力nに対して、チャレンジはf(n、1)の出力を要求します。

正の整数のN及びkのようにkが≤N 、下限を有する少なくとも一つのパーティションがあるK:シングルトンリスト[n]はn = kの場合(特にn = 1の場合)、これが唯一の適格なパーティションです。一方、k> nの場合、解はまったくありません。

k <nの場合、次のように左から右に構築することにより、残りのパーティションを再帰的にカウントできます。k≤j≤n / 2のようなjごとに、パーティション[x 1、⋯、x m ] = [j、y 1、⋯、y m-1 ]を構築できます。y 1 +⋯+ y m-1 = n-jの場合にのみ、x 1 +⋯+ x m = nとなる。また、X 1 ≤⋯≤X Mの場合に限り、J≤Y 1 ≤⋯≤Y M-1

したがって、パーティションがxはNから始まるJとして計算することができる- F(J、J n)が有効なパーティション数、yはj≤n / 2であることを要求することにより、j≤n -jであることが保証されるため、少なくとも1つのyが存在します。私たちは、このようにカウントすることができ、すべてのパーティションのnを加算することによって1を(のために[N]と)- (J、J n)はFの全ての有効な値については、J

コードは数学関数fの簡単な実装です。さらに、kをデフォルトで1に設定するため、入力nf(n)f(n、1)の値を計算します。


ああ、これはすごい!これがどのように機能するかについて説明を追加できますか?

回答を編集しました。不明な点がある場合はお知らせください。
デニス

3

J37 35バイト

0{]1&((#.]*>:@#.~/.~&.q:@#\%#),])1:

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

説明

0{]1&((#.]*>:@#.~/.~&.q:@#\%#),])1:  Input: n
                                 1:  Constant 1
  ]                                  Get n
   1&(                          )    Repeat n times on x = [1]
                          \            For each prefix
                         #               Length
                      q:@                Prime factors
                 /.~&                    Group equal factors
              #.~                        Compute p+p^2+...+p^k for each group
           >:@                           Increment
                    &.q:                 Product
                           %           Divide
                            #          Length
         ]                             Get x
          *                            Times
   1   #.                              Sum
                              ,        Joim
                               ]       Get x
                                       Set this as next value of x
0{                                   Select value at index 0

私はumb然としていますが、説明を投稿してもいいですか?
コール

1
@coleこれは、p(0)= 1の解法から始まり、式を使用して次の解法を構築する反復アプローチですp(n) = sum(sigma(n-k) * p(k) for k = 0 to n-1) / n。コードを大幅に短縮できないと思われる場合は、後でコードの説明を追加します。
マイル

2

JavaScript、125 121バイト

n=>(z=(a,b)=>[...Array(a)].map(b))(++n**n,(_,a)=>z[F=z(n,_=>a%(a/=n,n)|0).sort().join`+`]=b+=eval(F)==n-1&!z[F],b=0)|b||1

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

警告:時間と空間の複雑さは指数関数的です。数が多いと非常に遅くなります。


2

Python 2、89バイト

Mr.Xcoderによる-9バイトnotjaganによる-1バイト

lambda n:len(p(n))
p=lambda n,I=1:{(n,)}|{y+(x,)for x in range(I,n/2+1)for y in p(n-x,x)}

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



@ Mr.XcoderラムダDを使用しなかった理由がわからない:
デッドポッサム

ヘヘ、¯\_(ツ)_/¯-あなたはそれを完全な機能を維持したい場合はところで、あなたは変数を必要としない、94バイト
氏Xcoder

@ Mr.Xcoderうん..しばらくの間codegolfから離れてさびた気分だ:c
死んだポッサム



0

Java 8(229バイト)

import java.util.function.*;class A{static int j=0;static BiConsumer<Integer,Integer>f=(n,m)->{if(n==0)j++;else for(int i=Math.min(m,n);i>=1;i--)A.f.accept(n-i,i);};static Function<Integer,Integer>g=n->{f.accept(n,n);return j;};}

ゴルフをしていない:

import java.util.function.*;

class A {
    static int j = 0;
    static BiConsumer<Integer, Integer> f = (n, m) -> {
        if (n == 0)
            j++;
        else
            for (int i = Math.min(m, n); i >= 1; i--)
                A.f.accept(n - i, i);
    };
    static Function<Integer, Integer> g = n -> {
        f.accept(n, n);
        return j;
    };
}



0

JavaScript ES7、69バイト

n=>(f=(i,s)=>i?[for(c of Array(1+n))f(i-1,s,s-=i)]:c+=!s)(n,n,c=0)&&c

JavaScript ES6、71バイト

n=>(f=(i,s)=>i?[...Array(1+n)].map(_=>f(i-1,s,s-=i)):c+=!s)(n,n,c=0)&&c

時間の複雑さO(n ^ n)なので、注意してください(私のコンピューターでは、明らかな遅延が表示されますF(6)

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