Ba số tam giác [đóng]


19

Sự miêu tả

Trước đây đã có khá nhiều thử thách khác liên quan đến những con số này và tôi hy vọng đây không phải là một trong số chúng.

Số tam giác thứ n bằng tổng của tất cả các số tự nhiên lên đến n , công cụ đơn giản. Có một trang wikipedia và một mục tại OEIS , cho những người muốn thông báo thêm cho mình.

Bây giờ, Gauss phát hiện ra rằng mọi số tự nhiên có thể được biểu thị dưới dạng tổng của ba số tam giác (bao gồm cả số này 0), và sẽ tốt hơn nếu có nhiều hơn một số, ví dụ 0 + 1 + 1 = 2.

Thử thách

Nhiệm vụ của bạn là viết một chương trình hoặc hàm, cho một số tự nhiên (bao gồm 0), in ba số tam giác tổng hợp với đối số. Bạn có thể in các số được phân tách bằng dấu cách, dưới dạng một mảng hoặc bằng một phương thức khác mà bạn thích. Tuy nhiên, không được phép sử dụng bất kỳ hàm dựng sẵn nào để lấy trực tiếp một mảng, một phạm vi hoặc bất kỳ hình thức thu thập nào khác có chứa danh sách các số tam giác (ví dụ một nguyên tử duy nhất tạo ra phạm vi).

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

9 -> 6 + 3 + 0 or 3 + 3 + 3
12 -> 6 + 6 + 0 or 6 + 3 + 3 or 10 + 1 + 1
13 -> 6 + 6 + 1
1 -> 1 + 0 + 0
0 -> 0 + 0 + 0

Lưu ý: Nếu có nhiều hơn một kết hợp có thể, bạn có thể in bất kỳ hoặc tất cả, nhưng bạn phải in bất kỳ kết hợp nào chỉ một lần, loại bỏ tất cả các kết hợp là kết quả của việc sắp xếp lại các kết hợp khác. Tôi thực sự đánh giá cao một liên kết thử và một lời giải thích, tôi thực sự thích xem cách bạn giải quyết vấn đề;)

Đây là , vì vậy sơ hở tiêu chuẩn áp dụng. Có thể câu trả lời ngắn nhất trong byte giành chiến thắng!


1
Đối với 12 bạn cũng có thể thực hiện 1 + 1 + 10.
Erik the Outgolfer 17/07/17

1
@steenbergh asẽ không luôn là số tam giác
Felipe Nardi Batista

3
Tôi có thể phân tích "các hàm dựng sẵn để trực tiếp lấy một mảng, một phạm vi hoặc bất kỳ hình thức thu thập nào khác có chứa một danh sách các số tam giác " theo hai cách, nhưng cả hai đều không có ý nghĩa. Điều đầu tiên cấm tất cả các nội dung trực tiếp có được một mảng, nhưng điều đó dường như cấm tất cả việc sử dụng các mảng trong mọi ngôn ngữ mà tôi biết; cái khác cấm các nội dung " trực tiếp lấy ... một phạm vi ... chứa danh sách các số tam giác ", nhưng tôi không biết điều đó có nghĩa gì.
Peter Taylor

2
Vì vậy, các hàm dựng sẵn có tham số nvà trả về danh sách các nsố tam giác đầu tiên được phép? Điều đó cảm thấy khá khó khăn đối với một số ngôn ngữ cụ thể, mặc dù tôi không biết đó là ngôn ngữ nào.
Peter Taylor

4
Tôi kêu gọi bạn để nâng hạn chế này. Tôi hứa với bạn rằng nó sẽ không cải thiện chất lượng câu trả lời giữa các ngôn ngữ hoặc sự công bằng theo cách bạn nghĩ.
Lynn

Câu trả lời:


8

05AB1E , 10 byte

Mã số:

ÝηO3ãʒOQ}¬

Giải trình:

Ý             # Compute the range [0 .. input]
 η            # Get the prefixes
  O           # Sum each prefix to get the triangle numbers
   3ã         # Cartesian repeat 3 times
     ʒ  }     # Keep elements that
      OQ      #   have the same sum as the input
         ¬    # Retrieve the first element

Sử dụng mã hóa 05AB1E . Hãy thử trực tuyến!


À ... vâng; đó là làm điều đó
Bạch tuộc ma thuật Urn

7

Python 2 , 99 byte

from random import*
n=input()
while 1:b=sample([a*-~a/2for a in range(n+1)]*3,3);n-sum(b)or exit(b)

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

Tôi khá ngạc nhiên vì nó ngắn hơn itertoolshoặc hiểu ba danh sách! Nó (cuối cùng) phun ra một câu trả lời ngẫu nhiên mỗi khi bạn chạy nó.

Hai 102:

n=input();r=[a*-~a/2for a in range(n+1)];print[(a,b,c)for a in r for b in r for c in r if a+b+c==n][0]
def f(n):r=[a*-~a/2for a in range(n+1)];return[(a,b,c)for a in r for b in r for c in r if a+b+c==n][0]

itertools có vẻ là 106:

from itertools import*;lambda n:[x for x in product([a*-~a/2for a in range(n+1)],repeat=3)if sum(x)==n][0]

+1 cho đầu ra ngẫu nhiên. :) Tôi cũng ngạc nhiên khi đưa ra giải pháp ngắn nhất (cho đến nay).
Kevin Cruijssen

Cảm ơn bạn rất nhiều cho phương pháp. Mã Ruby tương ứng có 57 byte.
Eric Duminil 17/07/17


3

Brachylog , 13 byte

⟦⟦ᵐ+ᵐj₃⊇Ṫ.+?∧

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

Làm thế nào nó hoạt động

⟦⟦ᵐ+ᵐj₃⊇Ṫ.+?∧  input: n
⟦              [0 1 ... n]
 ⟦ᵐ            [[0] [0 1] [0 1 2] ... [0 1 ... n]]
   +ᵐ          [0 1 3 ... n(n+1)/2]
     j₃        [0 1 3 ... n(n+1)/2 0 1 3 ... n(n+1)/2 0 1 3 ... n(n+1)/2]
       ⊇       is a superset of
        Ṫ      a list of three elements 
         .     which is the output
          +?   which sums up to be the input

2

MATL , 18 byte

Q:qYs3Z^t!sG=fX<Y)

Điều này đưa ra kết quả đầu tiên theo thứ tự từ điển.

Hãy thử nó tại MATL Online!

Giải trình

Q     % Implicitly input n. Add 1
:     % Range (inclusive, 1-based): gives [1 2 ... n+1]
q     % Subtract 1 (element-wise): gives [0 1 ... n]
Ys    % Cumulative sum
3Z^   % Cartesian power with exponent 3. Gives a matrix where each row is a
      % Cartesian tuple
t     % Duplicate
!s    % Sum of each row
G=    % Does each entry equal the input?
f     % Find indices that satisfy that condition
X<    % Minimum
Y)    % Use as row index into the Cartesian power matrix. Implicitly display

2

Haskell, 66 59 byte

Cảm ơn đã cho phép xuất ra tất cả các giải pháp, đó là sự phân tâm hấp dẫn! Tôi rất vui khi không cần trích xuất một giải pháp và có thể chỉ cung cấp cho họ tất cả những gì tôi không nhận thấy chi phí đến từ việc tránh các giải pháp được thẩm thấu. Nhận xét của @ Lynn đã giải thích điều đó cho tôi và để tôi lưu 7 byte.

f n|l<-scanl(+)0[1..n]=[(a,b,c)|c<-l,b<-l,a<-l,a+b+c==n]!!0

Điều này liên kết quá nhiều số tam giác lvà kiểm tra tất cả các kết hợp.


Không bỏ các a>=b,b>=cđiều kiện và chỉ !!0nhập vào mã của bạn cũng là một câu trả lời hợp lệ? Xuất ra tất cả các giải pháp không thực sự giúp bạn ở đây.
Lynn

@Lynn Tất nhiên là bạn đúng, tôi đã bị phân tâm. Cảm ơn!
Christian Sievers

2

Võng mạc , 63 59 byte

.+
$*
^((^1|1\2)*)((1(?(4)\4))*)((1(?(6)\6))*)$
$.1 $.3 $.5

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. (1(?(1)\1))*là một công cụ so sánh số tam giác tổng quát, nhưng đối với số tam giác đầu tiên, chúng ta có thể lưu một vài byte bằng cách sử dụng ^cho kết quả khớp ban đầu.


1

PHP , 351 byte

$r=[];function f($a=[],$c=0){global$argn,$t,$r;if($c<3){$n=$argn-array_sum($a);$z=array_filter($t,$f=function($v)use($n,$c){return$v>=$n/(3-$c)&&$v<=$n;});foreach($z as$v){$u=array_merge($a,[$v]);if(($w=$n-$v)<1){if(!$w){$u=array_pad($u,3,0);sort($u);if(!in_array($u,$r)){$r[]=$u;}}}else f($u,$c+1);}}}for($t=[0];$argn>$t[]=$e+=++$i;);f();print_r($r);

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


1

Python 3 , 119 byte

lambda n:[l for l in combinations_with_replacement([(t**2+t)/2for t in range(n)],3)if sum(l)==n]
from itertools import*

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

Cảm ơn @WheatWizard đã lưu 12 byte!


Của bạn map(và có lẽ bộ lọc của bạn) có thể được viết ngắn hơn như là một sự hiểu biết danh sách.
Phù thủy lúa mì


@WheatWizard cảm ơn vì ý tưởng này, tôi không thể tin rằng tôi đã không nghĩ đến việc hiểu danh sách chomap
Chase Vogeli

Các đối tượng bộ lọc là đầu ra hoàn toàn hợp lệ, nhưng nếu bạn muốn xuất ra một danh sách, bạn có thể sử dụng một biểu tượng như vậy[*filter(...)]
Wheat Wizard

1
Những gì tôi đã thử (x,y,z) for x,y,z in...là dài hơn của bạn l for l in...mà có khả năng cho sự khác biệt đó.
Đuổi theo Vogeli

1

C / C ++ - 197 byte

#include<stdio.h>
#define f(i,l,u) for(int i=l;i<=u;i++)
int t(int n){return n>1?n+t(n-1):n;}
int c(int n){f(a,0,n)f(b,a,n)f(c,b,n)if(t(a)+t(b)+t(c)==n)return printf("%d %d %d\n",t(a),t(b),t(c));}

Cú đòn:

#include<stdio.h>

Cần thiết cho printf. Có thể được tách ra cho các phiên bản nhất định của C

#define f(i,l,u) for(int i=l;i<=u;i++)

Tiết kiệm không gian cho vòng lặp.

int t(int n){return n>1?n+t(n-1):n;}

Đánh giá tam giác đệ quy.

int c(int n){f(a,0,n)f(b,a,n)f(c,b,n)if(t(a)+t(b)+t(c)==n)return printf("%d %d %d\n",t(a),t(b),t(c));}

Anh chàng này làm việc nặng. Ba lồng cho các vòng lặp lặp lại a, b, c từ 0 đến n, lưu ý rằng b và c mỗi lần lặp từ giá trị trước lên đến n. Không nhất thiết phải cắt lặp đi lặp lại như thế kể từ khireturn sắp tới trong một phút sẽ giải quyết vấn đề "trùng lặp".

Ở cấp độ bên trong, nếu tổng của ba số tam giác == giá trị mong muốn, hãy in các hình tam giác và trả về.

Bạn có thể xóa returntừ khóa một cách hợp pháp và chuyển đổi kiểu trả về của c thành void để lưu thêm một vài byte và in tất cả các giải pháp có thể. Đó là vì lý do này mà lặp đi lặp lại được giới hạn, nếu tất cả các vòng chạy từ 0để nnó có thể gây ra các bản sao.


1

Toán học, 63 byte

(t=#;#&@@Select[Table[i(i+1)/2,{i,0,t}]~Tuples~{3},Tr@#==t&]‌​)&

Với cú pháp infix và cách nhận được Firstđiều đó giúp tiết kiệm được 2 byte , (t=#;#&@@Select[Table[i(i+1)/2,{i,0,t}]~Tuples~{3},Tr@#==t&])&cho 62 byte.
numbermaniac

Tuyệt vời, tôi sẽ chỉnh sửa
J42161217

0

CJam , 26 byte

{_),[{\_@+}*]3m*_{:+}%@#=}

Cổng câu trả lời MATL của tôi. Đây là một khối ẩn danh dự kiến ​​đầu vào trên ngăn xếp và thay thế nó bằng mảng đầu ra.

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


0

R , 66 byte

n=scan();b=expand.grid(rep(list(cumsum(0:n)),3));b[rowSums(b)==n,]

Thuật toán vũ phu; đọc ntừ stdin và trả về một khung dữ liệu trong đó mỗi hàng là sự kết hợp của 3 số tam giác cộng lại n. Nếu cần, tôi chỉ có thể trả về hàng đầu tiên cho +4 byte.

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


0

Java 8, 164 byte

n->{int t[]=new int[n+1],i=0,j=0;for(;i<=n;)if(Math.sqrt(8*i+++1)%1==0)t[j++]=i-1;for(int a:t)for(int b:t)for(int c:t)if(a+b+c==n)return new int[]{c,b,a};return t;}

Giải trình:

Hãy thử nó ở đây.

n->{                     // Method with int parameter and int-array return-type
  int t[]=new int[n+1],  //  Create an int-array to store triangular numbers
      i=0,j=0;           //  Two index-integers
  for(;i<=n;)            //  Loop (1) from 0 to `n` (inclusive)
    if(Math.sqrt(8*i+++1)%1==0) 
                         //   If `i` is a triangular number
      t[j++]=i-1;        //    Add it to array `t`
                         //  End of for-loop (1) (implicit / single-line body)
  for(int a:t)           //  Loop (2) over the triangular numbers
    for(int b:t)         //   Inner loop (3) over the triangular numbers
      for(int c:t)       //    Inner loop (4) over the triangular numbers
        if(a+b+c==n)     //     If the three triangular numbers sum equal the input
          return new int[]{c,b,a};
                         //      Return these three triangular numbers as int-array
                         //    End of loop (4) (implicit / single-line body)
                         //   End of loop (3) (implicit / single-line body)
                         //  End of loop (2) (implicit / single-line body)
  return t;              //  Return `t` if no sum is found (Java methods always need a
                         //  return-type, and `t` is shorter than `null`;
                         //  since we can assume the test cases will always have an answer,
                         //  this part can be interpret as dead code)
}                        // End of method

0

JavaScript, 108 byte

r=[],i=a=b=0
while(a<=x)r.push(a=i++*i/2)
for(a=0;a<3;){
b=r[i]
if(b<=x){
x-=b
a++
console.log(b)}
else i--}

Giải trình

x đại diện cho đầu vào

while(a<=x)r.push(a=i++*i/2) Tạo một mảng gồm tất cả các số tam giác lên đến x

Các forvòng lặp in ra số tam giác cao nhất ít hơn x, sau đó trừ con số từ x, đối với ba lần lặp lại. (về cơ bản là một thuật toán tham lam)


Bạn đã có cùng một vấn đề tôi làm: bằng cách lấy số tam giác lớn nhất <= x ở mỗi bước, bạn không được đảm bảo có số tam giác cho vị trí thứ 3 của mình. Kiểm tra đầu ra của bạn cho x = 103:91 + 10 + 1 = 102
asgallant

0

Bình thường, 19 byte

Tôi nên ra khỏi thực hành với Pyth, đó là không đúng sự thật: /

hfqQsT.C*3+0msSdSQ3

Dùng thử ở đây .

hfqQsT.C*3+0msSdSQ3  Implicit: Q=input()

                SQ   Range 1-n
            m        Map the above over d:
              Sd       Range 1-d
             s         Sum the above
                     Yields [1,3,6,10,...]
          +0         Prepend 0 to the above
        *3           Triplicate the above
      .C          3  All combinations of 3 of the above
 f                   Filter the above over T:
    sT                 Where sum of T
  qQ                   Is equal to input
h                    Take the first element of that list

Bạn có thể có thể lưu một byte bằng cách bỏ qua bộ chọn cho phần tử danh sách đầu tiên vì bạn cũng được phép in tất cả các giải pháp có thể.
racer290

@ racer290 Thậm chí tốt hơn, mặc dù kết quả sẽ ở dạng [[a, b, c], [d, e, f]] - điều đó có ổn không?
Sok

@ racer290 Trên thực tế, không, việc lọc các bản sao sẽ không được miễn phí bởi vẻ ngoài của mọi thứ, vì vậy nó sẽ không còn ngắn nữa: c
Sok


0

Ruby 61 57 55 byte

Lấy cảm hứng từ câu trả lời Python của Lynn . Nó tạo ra các bộ ba ngẫu nhiên cho đến khi đạt được số tiền mong muốn:

->n{x=Array.new 3{(0..rand(n+1)).sum}until x&.sum==n;x}

Nó đòi hỏi Ruby 2.4. Trong Ruby 2.3 trở lên, đó là lỗi cú pháp và Range#sumkhông được xác định. Phiên bản dài hơn này (64 byte) là cần thiết cho Ruby 2.3:

->n{x=Array.new(3){(a=rand(n+1))*-~a/2}until x&.inject(:+)==n;x}

Đây là một thử nghiệm nhỏ:

f=->n{x=Array.new 3{(0..rand(n+1)).sum}until x&.sum==n;x}
# => #<Proc:0x000000018aa5d8@(pry):6 (lambda)>
f[0]
# => [0, 0, 0]
f[13]
# => [0, 3, 10]
f[5]
# => [3, 1, 1]
f[27]
# => [21, 3, 3]
f[27]
# => [0, 21, 6]
f[300]
# => [3, 21, 276]

Dùng thử trực tuyến với Ruby 2.3!


0

Javascript (ES6), 108 byte - đã sửa

Lấy một số nguyên làm đầu vào, xuất ra một mảng [a, b, c]chứa danh sách các số tam giác được sắp xếp a + b + c = x, trong đó asố tam giác lớn nhất nhỏ hơn hoặc bằng đầu vào và blà số tam giác lớn nhất nhỏ hơn hoặc bằng số trừ đầu vào a.

x=>{t=[0],t.f=t.forEach,i=j=k=0;for(;j<x;t[i]=j+=i++);t.f(a=>t.f(b=>t.f(c=>a+b+c==x?k=[a,b,c]:0)));return k}

Giải trình

x=>{
    t=[0],                               // initialize an array of triangle numbers
    t.f=t.forEach,                       // copy forEach method into t.f,
                                         // saves a net of 4 bytes
    i=j=k=0;
    for(;j<x;t[i]=j+=i++);               // populate t with all triangle numbers that
                                         // we could possibly need
    t.f(                                 // loop over all t
        a=>t.f(                          // loop over all t
            b=>t.f(                      // loop over all t
                c=>a+b+c==x?k=[a,b,c]:0  // if a+b+c = x, set k = [a,b,c], else noop
                                         // using a ternary here saves 1 byte vs
                                         // if statement
                                         // iterating over t like this will find all
                                         // permutations of [a,b,c] that match, but
                                         // we will only return the last one found,
                                         // which happens to be sorted in descending order
            )
        )
    );
    return k
}


Bạn không giải thích phần thú vị nhất: tại sao là x-m-nsố tam giác, tức là tại sao nó lại hoạt động?
Christian Sievers

Cũng nguy hiểm, hóa ra nó không được đảm bảo. Tất cả các trường hợp thử nghiệm tôi đã sử dụng chỉ để tạo ra một bộ ba số tam giác hợp lệ. Trở lại với bản vẽ.
asgallant

Cố định bây giờ, ít hài lòng với giải pháp này <; o (nhưng ít nhất nó hoạt động.
asgallant
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.