Fermat'ın çokgen sayı teoremi


24

Fermat'ın çokgen sayı teoremi her pozitif tam sayı en toplamı olarak ifade edilebileceğini belirtmektedir -gonal sayı. Bu, her pozitif tamsayının en fazla üç üçgen sayısının, dört kare sayının, beş beşgen sayının vb. Toplamı olarak ifade edilebileceği anlamına gelir. Göreviniz, bir tamsayıyı almak ve tamsayıyı almak ve -gonal hangi toplamı tamsayılar .n nxs3sx

inci -gonal tamsayıdır ve , birkaç yolla tanımlanabilmektedir. Olmayan matematik-y bir şekilde olmasıdır th -gonal sayıda düzenli bir çokgen olarak imal edilebilir iki, uzunluk, her . Örneğin, (üçgen sayılar) için:nsn1s3nssns=3

üçgenler

Bkz burada daha büyük olan örnekler için .s

Matematik-y tanımlama için aşağıdaki formül kullanılarak bir verir, inci -gonal sayısı:P(n,s)ns

P(n,s)=n2(s-2)-n(s-4)2

Burada Wikipedia sayfasında verilmiştir .

Giriş

İki pozitif tamsayı, ve , s \ ge 3 koşuluyla . Bu tamsayıları dilinizdeki en doğal ifadeyle girebilirsiniz (ondalık, unary, Kilise rakamları, tamsayı değerli kayan nokta sayıları vb.).sxs3

Çıktı

Tamsayılar, bir listesi L bir maksimum uzunluk ile, s toplamı, L eşittir x ve integers L olan s -gonal tamsayılardır. Yine, tamsayılar, kendi dilinizdeki doğal gösterimde, herhangi bir belirgin, tutarlı ayırıcı ile (yani ondalık çıktı için ondalık olmayan karakter (ler, unary çıktı için kullanılandan farklı bir karakter, vb.) Çıkarılabilir.)

kurallar

  • Girişler veya çıkışlar hiçbir zaman diliniz için tamsayı sınırını aşmaz
  • L sipariş vermek zorunda değil
  • Birden fazla olası çıkış durumunda, herhangi biri veya tümü kabul edilebilir
  • Bu olduğundan, bayt cinsinden en kısa kod kazanır.

Test durumları

   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


Çıktının bazı sıfır dolguları olabilir mi? Mesela düşünmek yerine sadece x=17, s=5baskı yapabilir miyiz ? 5,12,0,0,05,12
kusur

@flawr Elveda aşmadığı dizinin uzunluğu gibi gayet bile dolgu maddesiyle,s
coinheringaahing Caird

Tekrarlara izin veriliyor mu yoksa Qgönderime ekleyeyim mi?
Jonathan Allan,

@JonathanAllan Tekrarlanan çıktılar mükemmel (eğer birden fazla çözüm
çıktıysa

Yanıtlar:


6

Haskell , 78 80 77 bayt

Biz ilk kartezyen ürününü hesaplamak s-Gonal sayılar ve ardından toplamları o ilk girişi bulmak .nn

s#n=[x|x<-mapM(map(\n->s*(n^2-n)`div`2+n*(2-n)))([0..n]<$[1..s]),sum x==n]!!0

Çevrimiçi deneyin!


6

JavaScript (ES6),  83  80 bayt

Çıktının en küçük terimini en üst düzeye çıkaran hızlı özyinelemeli arama.

Girişi olarak alır (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])

Çevrimiçi deneyin!

formül

JS'de s köşegen sayıları hesaplamak için 0-bazlı bir formül kullanmak , yani n=0 ile başlamak ve P(n+1,s) hesaplamak için daha kısa olduğu ortaya çıkmaktadır :

P(n+1,s)=((n+1)2(s-2)-(n+1)(s-4))/2=(n2(s-2)+ns+2)/2=-(n+1)((n-1)-ns/2)

14 bayt ile yazılabilir:

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

Yorumlananlar

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 Daha sonra tamir etmeye çalışabilirim. Şimdilik kaldırıldı.
Arnauld,

Teşekkürler. Bekliyorum!
AZTECCO


4

Haskell , 55 bayt

n%s=[l|l<-mapM(\_->scanl(+)0[1,s-1..n])[1..s],sum l==n]

Çevrimiçi deneyin!

Tüm olası çözümleri çıkarır. S-gonal sayılarını aritmetik ilerlemenin kümülatif toplamı olarak tanımlar.

1, s-2, 2*s-3, 3*s-4, ...

3

Jöle , 17 bayt

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

sSolda ve xsağda kabul eden bir (çok çok verimsiz) dyadic Link , tamsayıların listesi olarak (en azalan sırayla) mümkün olan en kısa cevabı verir.

Çevrimiçi deneyin! - çok daha yüksek değerler için denemek pek değil!

Nasıl?

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 Tamamen iyi, 60 saniyede TIO'da zaman aşımına uğradı (zaman aşımına uğrayacağından çok daha küçük giriş numarasından bile eminim). Cevabımda işaret ettiğim gibi, bu "çok çok verimsiz" ve "çok daha yüksek değerler için denemek için çok fazla bir nokta yok!". Unutmayın, bir kod-golf çözümü için verilen kod yalnızca sonsuz kaynak verilen çalışmaya ihtiyaç duyar.
Jonathan Allan

tamam s = 3 ve n = 5 ile test ettim ve 12 saniye sürdü! Bu verimsiz çözümü sevdim ve test etmek neredeyse imkansız olsa bile, size güveneceğim :) teşekkür ederim!
AZTECCO

1
xs

3

Ruby , 79 bayt

n ss

n2(s-2)-n(s-4)2n(ns-2n-s+4)2

->n,s{a=(0..n).map{|i|i*(i*s-2*i-s+4)/2};a.product(*[a]*~-s).find{|a|a.sum==n}}

Çevrimiçi deneyin!



2

Retina , 111 bayt

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

Çevrimiçi deneyin! Link, test durumlarını içerir. Sırayla girişi alır s n. Açıklama:

\d+
*

Birliğe dönüştür.

~(`

Kalan aşamaları işledikten sonra, onlara bir Retina programı gibi davranın ve aynı giriş üzerinde uygulayın.

$
$"

Satırı çoğalt.

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

İlk kopyayı, ilk sayıdan s satlayan ve sonra -gonal sayılarla eşleşen normal bir ifadeyle değiştirin . Sayıların kendisi tekli yakalama gruplarında yakalanır ve sçiftli yakalama grupları tüm sayıların -genal olmasını sağlamak için kullanılır .

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

İkinci kopyayı tek yakalama gruplarının boşlukla ayrılmış bir listesiyle değiştirin.

Örnek olarak, bir giriş için oluşturulan kod 5 17aşağıdaki gibidir:

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

1

APL (NARS), 149 karakter, 298 bayt

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}

"0 = ≢b" çözümlerini bulamazsanız, (ns) girişinin dönüşünden, n kere 1; Aksi takdirde, daha az ekli olan s sayılarının toplamını döndürürdü ...

Ölçek:

  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

Bunun sorunu: Bir çözüm bulamıyorsa, toplamda bir miktar tekrar vardır.


0

C ++ (clang) , 198 bayt

#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;}

Çevrimiçi deneyin!

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.