ทฤษฎีบทจำนวนเหลี่ยมของแฟร์มาต์


24

ทฤษฎีบทจำนวนเหลี่ยมของแฟร์มาต์ระบุว่าจำนวนเต็มบวกทุกค่าสามารถแสดงเป็นผลรวมของจำนวนตัวเลขn nซึ่งหมายความว่าทุกจำนวนเต็มบวกสามารถแสดงเป็นผลรวมของตัวเลขสามเหลี่ยมได้มากถึงสามรูปสามเหลี่ยม, สี่ตาราง, ห้าเหลี่ยมห้าเหลี่ยมเป็นต้นงานของคุณคือการใช้จำนวนเต็มบวกx , และจำนวนเต็มs3และส่งออกs -gonalจำนวนเต็มซึ่งรวมไปxx

n -th s -gonal จำนวนเต็มที่n1และs3 , สามารถกำหนดในสองวิธี วิธีที่ไม่ใช่คณิตศาสตร์-Y เป็นที่n TH sจำนวน -gonal สามารถสร้างเป็นรูปเหลี่ยมปกติกับsด้านข้างแต่ละความยาวnnตัวอย่างเช่นสำหรับs=3 (ตัวเลขสามเหลี่ยม):

สามเหลี่ยม

ดูที่นี่สำหรับตัวอย่างที่มีขนาดใหญ่ss

นิยามคณิตศาสตร์ -y คือการใช้สูตรสำหรับP(n,s)ซึ่งให้ผลเป็นจำนวนn -th s -gonal:

P(n,s)=n2(s2)n(s4)2

ซึ่งจะได้รับในหน้าวิกิพีเดียที่นี่

อินพุต

สองจำนวนเต็มบวกsและxกับสภาพs3 3 คุณสามารถป้อนจำนวนเต็มเหล่านี้ในรูปแบบที่เป็นธรรมชาติมากที่สุดในภาษาของคุณ (ทศนิยม, ไม่เป็นเอกภาพ, ตัวเลขในโบสถ์, ตัวเลขทศนิยมที่มีค่าเป็นจำนวนเต็มเป็นต้น)

เอาท์พุต

รายการจำนวนเต็ม, Lมีความยาวสูงสุดของsโดยที่ผลรวมของLเท่ากับxและจำนวนเต็มทั้งหมดในLเป็นจำนวนเต็มs -gonal อีกครั้งจำนวนเต็มอาจถูกเอาท์พุทในการเป็นตัวแทนตามธรรมชาติในภาษาของคุณโดยมีตัวคั่นที่ชัดเจนและสอดคล้องกัน (เช่นอักขระที่ไม่ใช่ทศนิยมสำหรับเอาต์พุตทศนิยม, อักขระที่แตกต่างจากที่ใช้สำหรับเอาต์พุตยูนารี ฯลฯ )

กฎระเบียบ

  • อินพุตหรือเอาต์พุตจะไม่เกินขีด จำกัด จำนวนเต็มสำหรับภาษาของคุณ
  • 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,0แทนเพียง5,12?
ข้อบกพร่อง

@ flawr ตราบใดที่ความยาวของอาเรย์ไม่เกินถึงแม้จะมีการเติมเต็ม แต่ก็ไม่เป็นไรs
caird coinheringaahing

อนุญาตการทำซ้ำหรือฉันควรเพิ่มการQส่งของฉันหรือไม่
Jonathan Allan

@JanathanAllan ผลลัพธ์ที่ออกมาซ้ำแล้วซ้ำอีกเป็นสิ่งที่ดีอย่างสมบูรณ์ (หากแสดงผลลัพธ์หลาย ๆ วิธี)
387267 caird coinheringaahing

คำตอบ:


6

Haskell , 78 80 77 ไบต์

เราคำนวณผลิตภัณฑ์ Cartesian แรกnหมายเลข S-gonal แล้วหาจากรายการแรกที่จำนวนเงินที่จะ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

ลองออนไลน์!


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 เพื่อคำนวณตัวเลขs -gonal ใน JS คือเริ่มต้นด้วยn=0และคำนวณP(n+1,s) :

P(n+1,s)=((n+1)2(s2)(n+1)(s4))/2=(n2(s2)+ns+2)/2=(n+1)((n1)ns/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 ฉันอาจลองแก้ไขในภายหลัง นำออกแล้วตอนนี้
Arnauld

ขอบคุณ รอเลย!
AZTECCO


4

Haskell , 55 ไบต์

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

ลองออนไลน์!

เอาต์พุตโซลูชันที่เป็นไปได้ทั้งหมด กำหนดหมายเลข s-gonal เป็นผลรวมสะสมของการดำเนินการทางคณิตศาสตร์

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

3

เยลลี่ขนาด 17 ไบต์

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

ลิงก์ dyadic A (ไม่มีประสิทธิภาพมาก) ยอมรับ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 มันดีอย่างสมบูรณ์มันหมดเวลากับ TIO ที่ 60 วินาที (ฉันค่อนข้างมั่นใจว่าแม้จำนวนอินพุตที่น้อยกว่าจะหมดเวลา) ในขณะที่ฉันชี้ให้เห็นในคำตอบของฉันนี่คือ "ไม่มีประสิทธิภาพมาก" และมี "ไม่มากนักลองมันสำหรับค่าที่สูงกว่ามาก!" โปรดจำไว้ว่ารหัสที่ให้สำหรับโซลูชันการเข้ารหัสกอล์ฟจะต้องใช้งานทรัพยากรที่ไม่มีขีด จำกัด เท่านั้น
Jonathan Allan

ตกลงฉันทดสอบด้วย s = 3 และ n = 5 และใช้เวลา 12 วินาที !! ฉันชอบโซลูชันที่ไม่มีประสิทธิภาพนี้และฉันจะเชื่อใจคุณแม้ว่ามันจะเป็นไปไม่ได้ที่จะทดสอบ :) ขอบคุณ!
AZTECCO

1
xs



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_
$$.$.($`$>`

แทนที่สำเนาที่สองด้วยรายการที่คั่นด้วยช่องว่างของกลุ่มการจับภาพคี่

ตัวอย่างโค้ดที่สร้างขึ้นสำหรับอินพุต5 17มีดังนี้:

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

1

APL (NARS), 149 chars, 298 bytes

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" มากกว่าการส่งคืนสำหรับอินพุต (ns), n คูณ 1; มิฉะนั้นจะส่งคืนผลรวมของตัวเลขที่มีส่วนเสริมน้อย ...

ทดสอบ:

  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 ++ (เสียงดังกราว) , 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.