Định lý số đa giác của Fermat


24

Định lý số đa giác của Fermat nói rằng mọi số nguyên dương có thể được biểu diễn dưới dạng tổng của tối đa đường chéo. Điều này có nghĩa là mọi số nguyên dương có thể được biểu thị bằng tổng của tối đa ba số tam giác, bốn số vuông, năm số ngũ giác, v.v. Nhiệm vụ của bạn là lấy một số nguyên dương và một số nguyên và để xuất ra số nguyên -gonal số nguyên mà tổng để .n nxs3sx

Các -thứ nguyên -gonal, nơi và , có thể được định nghĩa trong một vài cách khác nhau. Cách phi toán học-y là th số -gonal có thể được xây dựng như một đa giác thường xuyên với bên, mỗi chiều dài . Ví dụ: với (số tam giác):nsn1s3nssns=3

Hình tam giác

Xem ở đây để biết ví dụ với một lớn hơn .s

Định nghĩa math-y là bằng cách sử dụng công thức cho , mang lại số thứ tự thứ :P(n,s)ns

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

được đưa ra trong trang Wikipedia ở đây .

Đầu vào

Hai số nguyên dương, và , với điều kiện . Bạn có thể nhập các số nguyên này theo cách biểu thị tự nhiên nhất trong ngôn ngữ của bạn (số thập phân, số nguyên, số Church, số dấu phẩy động có giá trị nguyên, v.v.).sxs3

Đầu ra

Một danh sách các số nguyên, , với độ dài tối đa , trong đó tổng bằng và tất cả các số nguyên trong là số nguyên . Một lần nữa, các số nguyên có thể được xuất ra trong biểu diễn tự nhiên trong ngôn ngữ của bạn, với bất kỳ dấu tách riêng biệt, nhất quán nào (để ký tự không thập phân cho đầu ra thập phân, một ký tự khác với ký tự được sử dụng cho đầu ra đơn nguyên, v.v.)LsLxLs

Quy tắc

  • Đầu vào hoặc đầu ra sẽ không bao giờ vượt quá giới hạn số nguyên cho ngôn ngữ của bạn
  • L không phải đặt hàng
  • Trong trường hợp có nhiều đầu ra có thể, bất kỳ hoặc tất cả đều được chấp nhận
  • Đây là vì vậy mã ngắn nhất tính bằng byte sẽ thắng

Các trường hợp thử nghiệm

   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


Đầu ra có thể có một số đệm không? Ví dụ, nếu chúng ta xem xét x=17, s=5chúng ta có thể xuất ra 5,12,0,0,0thay vì chỉ 5,12?
flawr

@flawr Miễn là độ dài của mảng không vượt quá , ngay cả với phần đệm, điều đó cũng ổnS
caird coinheringaahing

Được lặp lại cho phép hoặc tôi nên thêm một Qvào trình của tôi?
Jonathan Allan

Câu trả lời:


6

Haskell , 78 80 77 byte

Chúng tôi tính toán sản phẩm cartesian của các số n s-gonal đầu tiên , và sau đó tìm mục đầu tiên tính tổng n .

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

Hãy thử trực tuyến!


6

JavaScript (ES6),  83  80 byte

Một tìm kiếm đệ quy nhanh trong đó tối đa hóa thuật ngữ nhỏ nhất của đầu ra.

Đưa đầu vào là (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])

Hãy thử trực tuyến!

Công thức

Hóa ra là ngắn hơn để sử dụng công thức dựa trên 0 để tính các số S chéo trong JS, nghĩa là bắt đầu bằng n= =0 và để tính P(n+1,S) :

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)

có thể được viết bằng 14 byte:

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

Đã bình luận

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 Tôi có thể cố gắng sửa nó sau. Loại bỏ ngay bây giờ.
Arnauld

Cảm ơn. Chờ đợi nó!
AZTECCO


4

Haskell , 55 byte

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

Hãy thử trực tuyến!

Đầu ra tất cả các giải pháp có thể. Xác định các số s-gonal là tổng tích lũy của tiến trình số học

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

3

Thạch , 17 byte

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

Liên kết dyadic (rất rất không hiệu quả) chấp nhận sở bên trái và xbên phải sẽ đưa ra câu trả lời ngắn nhất có thể dưới dạng danh sách các số nguyên (được sắp xếp tăng dần).

Hãy thử trực tuyến! - không có nhiều điểm thử nó cho giá trị cao hơn nhiều!

Làm sao?

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 Điều đó hoàn toàn ổn, thời gian trên TIO hết 60 giây (tôi khá chắc chắn số đầu vào nhỏ hơn rất nhiều so với thời gian chờ). Như tôi đã chỉ ra trong câu trả lời của mình, đây là "rất rất không hiệu quả" và rằng "không có nhiều điểm để thử nó cho các giá trị cao hơn nhiều!". Hãy nhớ rằng, mã được cung cấp cho một giải pháp mã golf chỉ cần công việc được cung cấp tài nguyên vô hạn.
Jonathan Allan

ok Tôi đã thử nghiệm với s = 3 và n = 5 và mất 12 giây !! Tôi thích giải pháp không hiệu quả này và tôi sẽ tin tưởng bạn, ngay cả khi gần như không thể kiểm tra nó :) cảm ơn bạn!
AZTECCO

1
xS

3

Ruby , 79 byte

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

Hãy thử trực tuyến!



2

Võng mạc , 111 byte

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

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Đưa đầu vào theo thứ tự s n. Giải trình:

\d+
*

Chuyển đổi sang unary.

~(`

Sau khi xử lý các giai đoạn còn lại, coi chúng như một chương trình Retina và thực hiện chúng trên cùng một đầu vào.

$
$"

Nhân đôi dòng.

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

Thay thế bản sao đầu tiên bằng một biểu thức chính quy bỏ qua số đầu tiên và sau đó khớp với các s ssố chéo. Các số được chụp trong các nhóm bắt lẻ và các nhóm bắt chẵn được sử dụng để đảm bảo rằng tất cả các số đều là sđường chéo.

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

Thay thế bản sao thứ hai bằng một danh sách được phân tách bằng dấu cách của các nhóm chụp lẻ.

Ví dụ, mã được tạo cho đầu vào 5 17là như sau:

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

1

APL (NARS), 149 ký tự, 298 byte

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}

nếu không tìm thấy giải pháp "0 = ≢b" hơn trả về cho (ns) đầu vào, n lần 1; nếu không, nó sẽ trả về tổng số s có ít cộng ...

kiểm tra:

  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

Vấn đề của điều này: Nó không tìm thấy một số giải pháp có một số lặp lại trong tổng số ...


0

C ++ (tiếng kêu) , 198 byte

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

Hãy thử trực tuyến!

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.