フェルマーの多角数定理


24

フェルマーの多角数定理は、すべての正の整数が最大対角数の合計として表現できると述べています。すべての正の整数は3つの三角形番号、4つの平方数、5五角数などあなたの仕事は、正の整数取ることですまでの和として表現することができることを、この手段、整数、および出力へ -合計される整数。n nxs3sx

目 -gonal整数、及び、いくつかの方法で定義することができます。非数学的な方法は、番目対角数を、それぞれの長さがである辺を持つ正多角形として構築できることです。たとえば、(三角形の数)の場合:nsn1s3nssns=3

三角形

より大きい例については、こちらをご覧ください。s

math-yの定義は、の式を使用することにより、番目対角数を生成します。P(nsns

Pns=n2s2ns42

これはウィキペディアのページにあります

入力

条件 2つの正の整数、および。言語で最も自然な表現でこれらの整数を入力できます(10進数、単項、教会の数字、整数値の浮動小数点数など)。sバツs3

出力

最大長の整数リスト。ここで、の合計は等しく、すべての整数は対角整数です。繰り返しますが、整数は、言語の自然な表現で出力される場合があり、明確で一貫したセパレータがあります(したがって、10進出力の場合は非10進文字、単項出力などに使用されるものとは異なる文字)LsLバツLs

ルール

  • 入力または出力が言語の整数制限を超えることはありません
  • Lは注文する必要はありません
  • 複数の可能な出力の場合、いずれかまたはすべてが受け入れられます
  • これはので、バイト単位の最短コードが勝ちます

テストケース

   x,  s => L
   1,  s => 1
   2,  s => 1, 1
   5,  6 => 1, 1, 1, 1, 1
  17,  3 => 1, 6, 10
  17,  4 => 1, 16
  17,  5 => 5, 12
  36,  3 => 36
  43,  6 => 15, 28
 879, 17 => 17, 48, 155, 231, 428
4856, 23 => 130, 448, 955, 1398, 1925


出力にゼロパディングを使用できますか?たとえば、単にではなくx=17, s=5出力できると考えたら?5,12,0,0,05,12
flawr

@flawr配列の長さが超えない限り、パディングを使用しても問題ありませんs
コヒーリング

繰り返しは許可さQれていますか?
ジョナサンアラン

@JonathanAllan繰り返し出力(複数の解を出力する場合)細かい完全である
coinheringaahing caird

回答:



6

JavaScript(ES6)、 83  80バイト

出力の最小項を最大化する高速再帰検索。

入力をとして受け取ります(s)(x)

s=>g=(x,n=0,a=[],y=~n*(~-n-n*s/2))=>x<y?x|a[s]?0:a:g(x,n+1,a)||g(x-y,n,[...a,y])

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

0 から始まる式を使用してJS s対角数を計算する、つまりn=0から開始してPn+1sを計算する方が短いことがわかります。

Pn+1s=n+12s2n+1s4/2=n2s2+ns+2/2=n+1n1ns/2

14バイトで書き込むことができます:

~n*(~-n-n*s/2)

コメント済み

s =>                         // main function taking s
  g = (                      // recursive function g
    x,                       // taking x
    n = 0,                   // start with n = 0
    a = [],                  // a[] = list of s-gonal numbers
    y =                      // y = P(n + 1, s)
      ~n * (~-n - n * s / 2) //   = -(n + 1) * ((n - 1) - n * s / 2)
  ) =>                       //
    x < y ?                  // if x is less than P(n + 1, s):
      x | a[s] ?             //   if x is not equal to 0 or a[] is too long:
        0                    //     failed: return 0
      :                      //   else:
        a                    //     success: return a[]
    :                        // else:
                             //   process recursive calls:
      g(x, n + 1, a) ||      //   preferred: try to increment n
      g(x - y, n, [...a, y]) //   fallback : try to use the current s-gonal number

@AZTECCO後で修正しようとするかもしれません。今のところ削除されました。
アーナルド

ありがとう。それを待っています!
アズテック



3

ゼリー、17 バイト

x’2;’ÄÄx⁸ŒPS⁼¥Ƈ⁹Ḣ

整数のリストとして可能な限り最短の回答を生成する(非常に非効率的な)ダイアディックリンク(s左からx右へ)(昇順で並べ替え)。

オンラインでお試しください!-はるかに高い値を試してみても意味がありません!

どうやって?

x’2;’ÄÄx⁸ŒPS⁼¥Ƈ⁹Ḣ - Link: s, x                    e.g.  5, 17
x                 - repeat (s) (x) times                [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]
 ’                - decrement (vectorises)              [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
  2;              - prepend a two                       [2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
    ’             - decrement (vectorises)              [1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
     Ä            - cumulative sums                     [1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49, 52]
      Ä           - cumulative sums                     [1, 5, 12, 22, 35, 51, 70, 92, 117, 145, 176, 210, 247, 287, 330, 376, 425, 477]
       x⁸         - repeat (each of those) (s) times    [1, 1, 1, 5, ..., 425, 477, 477, 477]
         ŒP       - power-set                           [[], [1], [1], ..., [1, 1], ..., [5, 22, 70], ... etc]
                      (this has 2^(x(s+1)) entries ...this example would have 2^(17(5+1)) = 2^102 = 5070602400912917605986812821504 entries!)
                      (Note: the lengths increase left to right)
              Ƈ   - filter keep if:
             ¥    -   last two links as a dyad:
           S      -     sum
            ⁼  ⁹  -     equals (x)?                     [[5,12], ... , [5,12], [1, 1, 5, 5, 5], ... , [1, 1, 5, 5, 5], [1, 1, 1, 1, 1, 12], ...]
                Ḣ - head                                [5,12]

@AZTECCOそれはまったく問題ありません。60秒でTIOでタイムアウトします(タイムアウトよりもはるかに小さい入力値であると確信しています)。私の答えで指摘しているように、これは「非常に非効率的」であり、「より高い値を試すのはあまり意味がない」ということです。コードゴルフソリューションに指定されたコードには、無限のリソースが与えられた場合にのみ作業が必要です。
ジョナサンアラン

s = 3とn = 5でテストしましたが、12秒かかりました!! 私はこの非効率的なソリューションが好きで、それをテストすることはほとんど不可能であっても、あなたを信頼します:)ありがとう!
アズテック

1
バツs



2

網膜、111バイト

\d+
*
~(`$
$"
0%["^_+ "|""]'$L$`\G_(?<=(?=___(_*))_+)
((_(?($.(2*$>`))$1\$.(2*$>`)))$*)
1%|' L$`\G_
$$.$.($`$>`

オンラインでお試しください!リンクにはテストケースが含まれます。入力を順番に受け取りますs n。説明:

\d+
*

単項に変換します。

~(`

残りのステージを処理した後、それらをRetinaプログラムとして扱い、同じ入力で実行します。

$
$"

行を複製します。

0%["^_+ "|""]'$L$`\G_(?<=(?=___(_*))_+)
((_(?($.(2*$>`))$1\$.(2*$>`)))$*)

最初のコピーを、最初の数字をスキップしてからs s対角数字に一致する正規表現に置き換えます。数字自体は奇数のキャプチャグループでキャプチャされ、偶数のキャプチャグループはすべての数字がs対角になるように使用されます。

1%|' L$`\G_
$$.$.($`$>`

2番目のコピーをスペースで区切られた奇数のキャプチャグループのリストに置き換えます。

例として、の入力に対して生成されるコード5 17は次のとおりです。

^_+ ((_(?(2)__\2))*)((_(?(4)__\4))*)((_(?(6)__\6))*)((_(?(8)__\8))*)((_(?(10)__\10))*)$
$.1 $.3 $.5 $.7 $.9

1

APL(NARS)、149文字、298バイト

r←f w;n;s;i;k
(n s)←w⋄r←⍬⋄→0×⍳s<3⋄i←1
→0×⍳n<k←2÷⍨(i×i×s-2)-i×s-4⋄r←r,k⋄i+←1⋄→2

h←{0=≢b←((v←↑⍵)=+/¨a)/a←{0=≢⍵:⊂⍬⋄m,(⊂1⌷⍵),¨m←∇1↓⍵}f⍵:v⍴1⋄k←↑⍋≢¨b⋄k⊃b}

解決策が見つからない場合は、(ns)入力に対してn回1回返すよりも「0 =≢b」です。それ以外の場合、加数の少ないsの合計を返します...

テスト:

  h 1 3
1 
  h 2 8
1 1 
  h 5 6
1 1 1 1 1 
  h 17 3
1 6 10 
  h 17 4
1 16 
  h 17 5
5 12 
  h 36 3
36 
  h 43 6
15 28 
  h 879 17
17 48 155 231 428 
  h 4856 23
321 448 596 955 2536 
  +/h 4856 23
4856

これの問題:いくつかの解決策が合計にいくつかの数字の繰り返しを見つけられない...


0

C ++(clang)、198バイト

#import<vector>
using V=std::vector<int>;V f(int n,int s){V _{0};int z=1,a=0,b=1,i,t;for(;a<n;b+=s-2)_.push_back(a+=b),++z;V o;for(t=a=0;t-n;b=++a)for(o=V(s),t=i=0;b;b/=z)t+=o[i++]=_[b%z];return o;}

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

V=vector<int> 
V _{0}; // initialized with one element =0 
int z=1, // vector size 
a=0,b=1,i,t;for(;a<n;b+=s-2)_.push_back(a+=b),++z;
// pushes polygons in V
V o; // vector to be returned 
for(t=a=0;t-n;b=++a) // ends when t=n
// loop to generate multi-dimension indexes
// for example a=1234 z=10
// a%z->4 , a/=z , a%z-> 3 , ... 2 , 1
for(o=V(s),t=i=0;b;b/=z)// loop to extract indexes
t+=o[i++]=_[b%z]; // put the sum in t and values in o
return o
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.