三个三角数[关闭]


19

描述

以前,有关这些数字还有很多其他挑战,我希望这一挑战不在其中。

n个三角数等于所有自然数之和,直到n个简单的东西。对于希望进一步了解自己的人,有一个Wikipedia页面OEIS条目

现在,高斯发现每个自然数都可以表示为三个三角数之和(包括0),并且多于一个数也很好,例如0 + 1 + 1 = 2

挑战

给定自然数(包括0),您的任务是编写一个程序或函数,并打印出三个加起来为参数的三角形数。您可以打印以空格,数组或其他喜欢的方法分隔的数字。但是,禁止使用任何内置函数直接获取包含三角数列表的数组,范围或任何其他形式的集合(例如,产生该范围的单个原子)。

测试用例

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

注意:如果有多个可能的组合,则可以打印任何一个或全部,但是必须仅打印一次任何组合,从而消除了由于重新排列其他组合而导致的所有组合。我真的很喜欢尝试链接和解释,我真的很乐意看到您如何解决问题;)

这是,因此存在标准漏洞。以字节为单位的最短答案可能会获胜!


1
12你也可以做到1 + 1 + 10
埃里克Outgolfer

1
@steenbergh a并不总是一个三角形数
Felipe Nardi Batista

3
我可以用两种方式解析“ 内置函数以直接获取数组,范围或包含三角数列表的任何其他形式的集合 ”,但它们都不有意义。第一个禁止所有直接获取数组的内建函数,但是这似乎禁止所有我知道的语言都使用数组。另一个禁止内建函数直接获取...包含三角形数字列表的范围 ”,但是我不知道这意味着什么。
彼得·泰勒

2
因此允许使用带参数n并返回第一个n三角形数字列表的内置函数?尽管我不知道哪种语言,但是这感觉是针对某些特定语言的。
彼得·泰勒

4
我敦促您解除这一限制。我向您保证,它不会以您的思维方式提高中介语回答质量或公平性。
林恩

Answers:


8

05AB1E,10个字节

码:

ÝηO3ãʒOQ}¬

说明:

Ý             # 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

使用05AB1E编码。在线尝试!


啊...是的 那会做到的。
魔术章鱼缸

7

Python 2,99个字节

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)

在线尝试!

我很惊讶这短于itertools或三重列表理解!每次运行时,它最终都会吐出一个随机答案。

两个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看起来是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为随机输出。:)我也惊讶于给出了最短的解决方案(到目前为止)。
凯文·克鲁伊森

非常感谢您的方法。相应的Ruby代码有57个字节。
埃里克·杜米尼尔


3

Brachylog,13个字节

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

在线尝试!

怎么运行的

⟦⟦ᵐ+ᵐ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字节

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

这将按字典顺序输出第一个结果。

MATL在线上尝试一下

说明

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字节

感谢您允许输出所有解决方案,这令人着迷!我很高兴不需要提取一个解决方案,而只给他们所有解决方案,而我没有注意到避免使用置换解决方案所带来的成本。@Lynn的话向我解释了这一点,让我节省了7个字节。

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

这将绑定足够多的三角数l并检查所有组合。


不删除a>=b,b>=c条件并仅!!0在代码后缀上也是一个有效的答案吗?输出所有解决方案并不能真正帮助您。
林恩

@琳恩你当然是对的,我分心了。谢谢!
Christian Sievers

2

视网膜63 59字节

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

在线尝试!链接包括测试用例。(1(?(1)\1))*是一个广义的三角数匹配器,但是对于第一个三角数,我们可以通过将其^用于初始匹配来节省一些字节。


1

PHP,351字节

$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);

在线尝试!


1

Python 3,119字节

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*

在线尝试!

感谢@WheatWizard节省了12个字节!


map(可能还有您的过滤器)可以写得更短些,以理解列表。
小麦巫师


@WheatWizard感谢您的想法,我不敢相信我没有想到列表的理解map
Chase Vogeli,2017年

过滤器对象是完全有效的输出,但是如果您要输出列表,则可以像这样使用splat[*filter(...)]
Wheat

1
我尝试过的是(x,y,z) for x,y,z in...比您更长的时间,l for l in...这可能是造成这种差异的原因。
Chase Vogeli '17年

1

C / C ++-197字节

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

吹一吹:

#include<stdio.h>

打印所需。某些版本的C可以省略

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

这个家伙做得很重。三个嵌套的for循环将a,b,c从0迭代到n,请注意b和c都从先前的值迭代到n。不必像这样修剪迭代,因为return一分钟之内就解决了“重复”问题。

在内部,如果三个三角形的数字之和为==所需值,请打印三角形并返回。

您可以合法地删除return关键字,并将c的返回类型转换为void以节省更多字节并打印所有可能的解决方案。正是由于这个原因,如果所有循环都从中0执行,则迭代受到限制,n这将导致重复。


1

Mathematica,63个字节

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

使用infix语法,该获取方式First节省了多达2个字节,共(t=#;#&@@Select[Table[i(i+1)/2,{i,0,t}]~Tuples~{3},Tr@#==t&])&62个字节。
numbermaniac

太好了,我将编辑
J42161217 '17


0

R,66个字节

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

蛮力算法;n从stdin 读取并返回一个数据帧,其中每行是3个三角形的组合,总计为n。如有必要,我只能返回+4字节的第一行。

在线尝试!


0

Java 8,164字节

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

说明:

在这里尝试。

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个字节

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

说明

x 代表输入

while(a<=x)r.push(a=i++*i/2) 创建一个由所有三角数组成的数组,最大为x

所述for环路打印小于最高三角形数x,然后减去从该数x,对于三次迭代。(基本上是贪婪算法)


您也遇到了同样的问题:通过在每个步骤中取最大三角形数<= x,就不能保证您的第3位有三角形数。检查您的输出是否x = 10391 + 10 + 1 = 102
令人震惊的2007年

0

Pyth,19个字节

这样出去与Pyth实践,这是不真实的:/

hfqQsT.C*3+0msSdSQ3

在这里尝试。

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

您可以通过省略第一个列表元素的选择器来节省一个字节,因为也可以打印所有可能的解决方案。
racer290

@ racer290甚至更好,尽管结果将采用[[a,b,c],[d,e,f]]的形式-可以吗?

@ racer290实际上,不,从外观上看,过滤重复项并不是免费的,所以它不会再短一些了:c
Sok Sok


0

Ruby 61 57 55个字节

受到Lynn的Python 答案的启发。它生成随机三元组,直到达到所需的总和:

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

它需要Ruby 2.4。在Ruby 2.3及更早版本中,这是语法错误,Range#sum没有定义。Ruby 2.3需要更长的版本(64字节):

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

这是一个小测试:

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]

使用Ruby 2.3在线试用!


0

Javascript(ES6),108个字节-已修复

以整数作为输入,输出一个[a, b, c]包含三角数排序列表的数组a + b + c = x,其中a是小于或等于输入b的最大三角数,小于或等于输入减号的最大三角数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}

说明

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
}


您没有解释最有趣的部分:为什么 x-m-n三角数,即为什么这样做有效?
Christian Sievers

好吧,Dangit,事实证明并不能保证。我使用的所有测试用例都碰巧产生了一个有效的三角形三元组。回到绘图板。
高大的

固定现在,用此溶液<更少快乐;○(但至少它的工作原理。
asgallant
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.