三角依赖


25

三角号是一个数字,是的总和n自然数从1到n。例如1 + 2 + 3 + 4 = 1010三角数也是如此。

给定正整数(0 < n <= 10000)作为输入(可以作为整数或字符串),返回可以添加到输入中以创建另一个三角数的最小可能三角数。

例如,给定input 26,将10结果相加36,这也是一个三角数。没有比10可以添加来26创建另一个三角数更小的三角数,因此10在这种情况下正确的结果是。

0 是一个三角数,因此,如果输入本身是一个三角数,则输出应为 0

测试用例

案例以以下格式给出 input -> output (resulting triangular number)

0     -> 0   (0)
4     -> 6   (10)
5     -> 1   (6)
7     -> 3   (10)
8     -> 28  (36)
10    -> 0   (10)
24    -> 21  (45)
25    -> 3   (28)
26    -> 10  (36)
34    -> 21  (55)
10000 -> 153 (10153)

计分

这是因此每种语言中最少的字节会获胜!


是不是26 -> 2
Okx

@Okx我犯了同样的错误,您需要找到一个三角形数字以添加到当前的三角形中以生成另一个三角形数字。
Martin Ender

2
有关。(边界重复)
Martin Ender

Answers:


21

Java 8,58 57字节

n->{int i=0,m=0;while(n!=0)n+=n<0?++i:--m;return-~i*i/2;}

在线测试套件

感谢Dennis节省了1个字节。


6
现在是Java,打高尔夫球!:)
OlivierGrégoire17年

4
@Computronium,操作顺序由Java语言规范保证。Java的刻意回避某些C的弱点
彼得·泰勒


2
return-~i*i/2;保存一个字节。
丹尼斯,

1
@Okx Java是原始类型的值传递和对象(包括数组)的引用传递。如果要实际输出相同的变量,则必须处于传递引用上下文中(在链接中明确说明)。我看到传递引用唯一可行的方法是传递int[]一个intas 而不是as参数。但这意味着以后要处理数组。这可能起作用:x->{int i=0,m=0,n=x[0];while(n!=0)n+=n<0?++i:--m;x[0]=-~i*i/2;},但是它是63个字节。
奥利维尔·格雷戈尔

7

MATL13 12字节

Emigna的05AB1E答案中使用一个想法(设置交集)删除了1个字节

Q:qYstG-X&X<

在线尝试!

说明

令- t(n) = 1 + 2 + ··· + n表示n第三角形数。

该代码利用了这样一个事实,即给定n的解决方案上限为t(n-1)。要看到这一点,请注意t(n-1) + n等于t(n),因此它是一个三角数。

以输入8为例。

Q:q   % Input n implicitly. Push [0 1 2 ... n]
      % STACK: [0 1 2 3 4 5 6 7 8]
Ys    % Cumulative sum
      % STACK: [0 1 3 6 10 15 21 28 36]
t     % Duplicate
      % STACK: [0 1 3 6 10 15 21 28 36], [0 1 3 6 10 15 21 28 36]
G-    % Subtract input, element-wise
      % STACK: [0 1 3 6 10 15 21 28 36], [-8 -7 -5 -2  2  7 13 20 28]
X&    % Set intersection
      % STACK: 28
X<    % Minimum of array (in case there are several solutions). Implicit display
      % STACK: 28

您能否Q通过关于边界性的论点来消除领导?
朱塞佩

@Giuseppe不,输入失败8。当输出等于界限时t(n-1),代码将其获取为t(n)-n。因此t(n)是必要的。无论如何,谢谢你的想法!
路易斯·门多

7

Java(OpenJDK 8),83字节

n->{int m=0,a=n,b;for(;a-->0;)for(b=0;b<=n;)m=2*n+b*~b++==a*~a?a*a+a:m;return m/2;}

在线尝试!

学分


1
好的答案(一如既往..)。当我发布我的 .. 时,我还没有注意到Java的答案。我的起初很短,但现在似乎不再了。:)
Kevin Cruijssen

谢谢!是的,我的第一个答案确实是多余的。我修复了它,使它更加数学化,尽管处理器也更加贪婪。我会在几秒钟内检查您的!
奥利维尔·格雷戈尔

我仍然不明白这里发生了什么。为什么运作?您每次都在更换m,这有什么意义?
V. Courtois

2
@ V.Courtois问题要求最小m。所以,我走的时候a0。“是的,但是您可能a*a+amb-loop中分配相同值的100倍”,是的,我不需要执行100次,但是我通过不破坏b-loop来获得字节。
奥利维尔·格雷戈尔

我看到了@OlivierGrégoire。所以这是故意的反效率:D
V. Courtois

5

Mathematica,46个字节

Min[Select[(d=Divisors[2#])-2#/d,OddQ]^2-1]/8&

4

Neim12 9字节

tS𝕊Λt𝕚)0𝕔

计算时间太长(但是在无限时间和内存的情况下可以工作),因此在链接中,我仅生成前143个三角数-using £𝕖,足以处理10,000个输入,但不足以超时。

警告:这可能在将来的版本中不起作用。如果是这样,用143代替£

说明:

t                 Infinite list of triangular numbers
 [ 𝕖]             Select the first  v  numbers
 [£ ]                              143
     S𝕊           Subtract the input from each element
       Λ  )       Only keep elements that are
        t𝕚          triangular
           0𝕔     Get the value closest to 0 - prioritising the higher number if tie

试试吧!


前143个三角形数字足以满足0到10000之间的任何输入吗?使用input时9998,预期结果为3118753,它比第143个三角数(即10296)高出许多。
奥利维尔·格雷戈尔

@OlivierGrégoire因为This takes too long to compute (but works given infinite time and memory)
Stephen

谢谢@StepHen,但这不是我所说的。我的意思是,句子“前143个三角数足以应付10,000个输入”是错误的。我没有做过的数学,但我相信,如果你需要10000左右(给予或采取)三角形数字处理的案件多达10000
奥利维尔格雷

@OlivierGrégoire我说它足以处理10,000个输入,但没有比这个数字少的任何数字。可以随意更改£为更大的数字,例如
200。– Okx

@Okx好吧,我第一次阅读时不太了解,谢谢您花时间解释:)
OlivierGrégoire17年

4

PHP,45字节

for(;!$$t;$t+=++$i)${$argn+$t}=~+$t;echo~$$t;

在线尝试!

是的较短变体 for(;!$r[$t];$t+=++$i)$r[$argn+$t]=~+$t;echo~$r[$t];

展开式

for(;!$$t;  # stop if a triangular number exists where input plus triangular number is a triangular number
$t+=++$i) # make the next triangular number
  ${$argn+$t}=~+$t; # build variable $4,$5,$7,$10,... for input 4 
echo~$$t; # Output result 

PHP,53字节

for(;$d=$t<=>$n+$argn;)~$d?$n+=++$k:$t+=++$i;echo+$n;

在线尝试!

在PHP 7中使用新的太空飞船运算符

展开式

for(;$d=$t<=>$n+$argn;) # stop if triangular number is equal to input plus triangular number 
  ~$d
    ?$n+=++$k  # raise additional triangular number
    :$t+=++$i; # raise triangular number sum
echo+$n; # Output and cast variable to integer in case of zero

PHP,55字节

for(;fmod(sqrt(8*($t+$argn)+1),2)!=1;)$t+=++$i;echo+$t;

在线尝试!


4

Java 8,110 102 100 93 92字节

n->{int r=0;for(;t(r)<-t(n+r);r++);return r;}int t(int n){for(int j=0;n>0;n-=++j);return n;}

-2个字节感谢@PeterTaylor
-7个字节,感谢@JollyJoker
-1个字节感谢@ceilingcat

说明:

在线尝试。

n->{                  // Method with integer as parameter and return-type
  int r=0;            //  Result-integer (starting at 0)
  for(;t(r)<-t(n+r);  //  Loop as long as neither `r` nor `n+r` is a triangular number
    r++);             //   And increase `r` by 1 after every iteration
  return r;}          //  Return the result of the loop

int t(int n){         // Separate method with integer as parameter and return-type
                      // This method will return 0 if the input is a triangular number
  for(int i=0;n>0;)   //  Loop as long as the input `n` is larger than 0
    n-=++j;           //   Decrease `n` by `j` every iteration, after we've raised `j` by 1
  return n;}          //  Return `n`, which is now either 0 or below 0

1
最容易阅读的Java解决方案:)
JollyJoker

@JollyJoker也许这就是为什么它最长的原因。;)还是因为我增加了解释?
凯文·克鲁伊森

不,我在想代码。我大概花了15分钟来弄清楚Peter Taylor的解决方案是如何工作的。即使没有评论,您也很清楚。
JollyJoker

3

Brachylog17 15字节

⟦{a₀+}ᶠ⊇Ċ-ṅ?∧Ċh

在线尝试!

说明

⟦                  [0, …, Input]
 {   }ᶠ            Find all…
  a₀+                …Sums of prefixes (i.e. triangular numbers)
       ⊇Ċ          Take an ordered subset of two elements
         -ṅ?       Subtracting those elements results in -(Input)
            ∧Ċh    Output is the first element of that subset

3

Python 2,59个字节

lambda n:min((r-2*n/r)**2/8for r in range(1,2*n,2)if n%r<1)

在线尝试!

这使用了以下三角数表征,然后t可以将其添加n以获得三角数:

8*t+1 = (r-2*s)^2用于(r,s)r*s==n和的除数对r

该代码采用所有此类三角数中的最小值。


3

果冻,8字节

0r+\ðf_Ḣ

在线尝试!

怎么运行的

0r+\ðf_Ḣ  Main link. Argument: n

0r        Build [0, ..., n].
  +\      Take the cumulative sum, generating A := [T(0), ..., T(n)].
    ð     Begin a dyadic chain with left argument A and right argument n.
      _   Compute A - n, i.e., subtract n from each number in A.
     f    Filter; keep only numbers of A that appear in A - n.
       Ḣ  Head; take the first result.

3

Japt24 23 16 15字节

ò å+
m!nNg)æ!øU

测试一下

ETH节省了1个字节


说明

    :Implicit input of integer U.
ò   :Create an array of integers from 0 to U, inclusive.
å+  :Cumulatively reduce by summing. Result is implicitly assigned to variable V.
m   :Map over U.
!n  :From the current element subtract...
Ng  :  The first element in the array of inputs (the original value of U).
æ   :Get the first element that returns true when...
!øU :  Checking if U contains it.
    :Implicit output of resulting integer.

我认为您可以使用保存一个字节æ!øV。除此之外,它看起来很棒:-)
ETHproductions '17



2

Mathematica,62个字节

(s=Min@Abs[m/.Solve[2#==(n-m)(n+m+1),{n,m},Integers]])(s+1)/2&

我不知道Mathematica,但是会Solve[2*#==m(m+1)-n(n+1)更短(如果可行)吗?
Kritixi Lithos

是的,我刚刚发布了答案并立即尝试打高尔夫球
J42161217,2015年

2

Python 2中78 71 70字节

保存了七个字节,thanx到ovs theespinosa

由于使用了neil的标记,x+9因此又节省了一个字节,足以检查所有自然数0 <= n <= 10000。也针对进行x+1验证,而不是x+9,它也可以工作。

x=input()
I={n*-~n/2for n in range(x+1)}
print min(I&{i-x for i in I})

在线尝试!


2
您可以使用n*-~n/2,而不是n*(n+1)/2
OVS

2
范围(x + 9)可以工作吗?
尼尔

2
您可以在第三行中使用{n*(n+1)/2for n in range(999)}代替显式set,也可以使用{}代替set
TheEspinosa

2

JavaScript(ES6),43 42字节

f=(n,a=s=0)=>n?f(n+=n>0?--s:++a,a):a*++a/2
<input type=number min=0 value=0 oninput=o.textContent=f(+this.value)><pre id=o>0

编辑:感谢@PeterTaylor,节省了1个字节。


设置全局变量是对默认参数的严重滥用。+1。但是FWIW可以替换-++s--s,以节省更多字节,就像我在独立派生但非常相似的Java版本中所做的那样。(附录:您还需要将测试更改为n>0)。
彼得·泰勒

@PeterTaylor Huh,所以n>s支票一直都是红鲱鱼!
尼尔

工作不是为8192
约尔格Hülsermann

@JörgHülsermann如果您指的是代码段,则浏览器的堆栈大小可能不够大,或者您可能需要具有实验性尾部调用优化功能的浏览器。另外,如果您使用NodeJS进行测试,请使用node --stack_size=增加其堆栈大小。
尼尔

2

Python 3中60 44个字节

f=lambda n,k=1:(8*n+1)**.5%1and f(n+k,k+1)+k

感谢@xnor的建议,它节省了16个字节!

在线尝试!

背景

n为非负整数。如果n是第k 三角数,我们有

条件

这意味着只有且仅当1 + 8n是一个奇数完美的正方形时,才会有一个自然的解决方案。显然,检查1 + 8n的奇偶校验不需要。

怎么运行的

递归函数n接受一个非负整数作为参数。当使用单个参数调用时,k默认为1

首先,(8*n+1)**.5%1测试n是否为三角数:如果(且仅当)为n,(8*n+1)**.5将产生一个整数,因此除以1的残差将产生0

如果模数为0,则and条件将失败,导致f返回0。如果在对f的初始调用中发生这种情况,请注意,这是正确的输出,因为n已经是三角形。

如果模数为正,则and条件成立并f(n+k,k+1)+k执行。这个呼叫˚F再次,递增Ñ通过ķķ1,然后添加ķ到的结果。

f(n 0,k 0最终返回0时,我们退出了递归。第一次调用中的第一个参数为n,第二个为n + 1,第三个为n + 1 + 2,直到最后n 0 = n + 1 +…k 0 -1。注意,n 0 -n是三角数。

同样,所有这些整数都将添加到最里面的返回值(0),因此根据需要,初始调用f(n)的结果n 0 -n


如果您也增加递归n,则可以编写n而不是(n+k)
xnor

或者,最好直接搜索三角数
xnor

哇,那比我尝试的要好得多。
xnor

2

C#(.NET Core)291281字节

class p{static int Main(string[]I){string d="0",s=I[0];int c=1,j,k;for(;;){j=k=0;string[]D=d.Split(' '),S=s.Split(' ');for(;j<D.Length;j++)for(;k<S.Length;k++)if(D[j]==S[k])return int.Parse(D[k]);j=int.Parse(D[0])+c++;d=d.Insert(0,$"{j} ");s=s.Insert(0,$"{j+int.Parse(I[0])} ");}}}

在线尝试! 以字符串作为输入并通过退出代码输出的程序。

感谢Kevin Cruijssen保存了10个字节


1
嗨,欢迎来到PPCG!除非挑战另有说明,否则您不需要完整的程序。默认值为程序/函数,因此在C#中也允许使用lambda。但是,如果您想使用程序,则可以在当前代码中进行一些操作:class p{static int Main(string[]I){string d="0",s=I[0];int c=1,j,k;for(;;){j=k=0;string[]D=d.Split(' '),S=s.Split(' ');for(;j<D.Length;j++)for(;k<S.Length;k++)if(D[j]==S[k])return int.Parse(D[k]);j=int.Parse(D[0])+c++;d=d.Insert(0,$"{j} ");s=s.Insert(0,$"{j+int.Parse(I[0])} ");}}}281个字节
Kevin Cruijssen

@KevinCruijssen感谢您的建议!使用for(;;)创建无限循环是一个不错的选择,并且我将确保更仔细地考虑使用var是否实际上比使用显式类型但结合声明更有效,并且我猜想在删除不必要的括号时会更加努力。至于程序与功能,我从lambda开始,但无法使其在TIO中运行。我知道实际上不需要TIO链接,但这是我希望在其他人的答案中看到的东西,因此我至少希望自己拥有类似的东西。
卡米尔·德拉卡里

我在C#lambdas tbh中也不是很好,我通常在Java中使用codegolf。但是我认为这应该是正确的。(252个字节)。另外,如果您还没有看到它,请阅读C#中的代码高尔夫球技巧<all语言>中的高尔夫球技巧。再次欢迎您,并向我+1。不错的第一答案。入住愉快。:)
Kevin Cruijssen

2

JavaScript(ES7),46 44字节

f=(n,x=r=0)=>(8*(n+x)+1)**.5%1?f(n,x+=++r):x

试试吧

o.innerText=(
f=(n,x=r=0)=>(8*(n+x)+1)**.5%1?f(n,x+=++r):x
)(i.value=8);oninput=_=>o.innerText=f(+i.value)
<input id=i type=number><pre id=o>


1
r=x=0工作吗?
Kritixi Lithos

遗憾的是,@ KritixiLithos。
毛茸茸的

1

05AB1E,8 个字节

ÝηODI-Ãн

在线尝试! 或作为测试套件

说明

Ý          # range [0 ... input]
 η         # prefixes
  O        # sum each
   D       # duplicate
    I-     # subtract input from each
      Ã    # keep only the elements in the first list that also exist in the second list
       н   # get the first (smallest)

1

Dyalog APL,19个字节

@KritixiLithos节省了6个字节

{⊃o/⍨o∊⍨⍵+o←0,+\⍳⍵}

在线尝试!

怎么样?

o←0,+\⍳⍵-分配o第一个三角形数字

o/⍨-筛选o依据

o∊⍨⍵+o-与之相加的三角数产生三角形

-并采取第一个


+\⍳⍵应该可以工作,而不是用来生成三角数的东西。
Kritixi Lithos

我认为是代替作品的⌊/
Kritixi Lithos



1

加++,68字节

L,RBFEREsECAAx$pBcB_B]VARBFEREsB]GEi$pGBcB*A8*1+.5^1%!!@A!@*b]EZBF#@

在线尝试!,或查看测试套件

甚至Java都在击败我。我真的需要在Add ++中添加一些设置命令

怎么运行的

L,    - Create a lambda function
      - Example argument:  8
  R   - Range;     STACK = [[1 2 3 4 5 6 7 8]]
  BF  - Flatten;   STACK = [1 2 3 4 5 6 7 8]
  ER  - Range;     STACK = [[1] [1 2] ... [1 2 3 4 5 6 7 8]
  Es  - Sum;       STACK = [1 3 6 10 15 21 28 36]
  EC  - Collect;   STACK = [[1 3 6 10 15 21 28 36]]
  A   - Argument;  STACK = [[1 3 6 10 15 21 28 36] 8]
  A   - Argument;  STACK = [[1 3 6 10 15 21 28 36] 8 8]
  x   - Repeat;    STACK = [[1 3 6 10 15 21 28 36] 8 [8 8 8 8 8 8 8 8]]
  $p  - Remove;    STACK = [[1 3 6 10 15 21 28 36] [8 8 8 8 8 8 8 8]]
  Bc  - Zip;       STACK = [[1 8] [3 8] [6 8] [10 8] [15 8] [21 8] [28 8] [36 8]]
  B_  - Deltas;    STACK = [-7 -5 -2 2 7 13 20 28]
  B]  - Wrap;      STACK = [[-7 -5 -2 2 7 13 20 28]]
  V   - Save;      STACK = []
  A   - Argument;  STACK = [8]
  R   - Range;     STACK = [[1 2 3 4 5 6 7 8]]
  BF  - Flatten;   STACK = [1 2 3 4 5 6 7 8]
  ER  - Range;     STACK = [[1] [1 2] ... [1 2 3 4 5 6 7 8]]
  Es  - Sum;       STACK = [1 3 6 10 15 21 28 36]
  B]  - Wrap;      STACK = [[1 3 6 10 15 21 28 36]]
  G   - Retrieve;  STACK = [[1 3 6 10 15 21 28 36] [-7 -5 -2 2 7 13 20 28]]
  Ei  - Contains;  STACK = [[1 3 6 10 15 21 28 36] [0 0 0 0 0 0 0 1]]
  $p  - Remove;    STACK = [[0 0 0 0 0 0 0 1]]
  G   - Retrieve;  STACK = [[0 0 0 0 0 0 0 1] [-7 -5 -2 2 7 13 20 28]]
  Bc  - Zip;       STACK = [[0 -7] [0 -5] [0 -2] [0 2] [0 7] [0 13] [0 20] [1 28]]
  B*  - Products;  STACK = [0 0 0 0 0 0 0 28]
  A   - Argument;  STACK = [0 0 0 0 0 0 0 28 8]
  8*  - Times 8;   STACK = [0 0 0 0 0 0 0 28 64]
  1+  - Increment; STACK = [0 0 0 0 0 0 0 28 65]
  .5^ - Root;      STACK = [0 0 0 0 0 0 0 28 8.1]
  1%  - Frac part; STACK = [0 0 0 0 0 0 0 28 0.1]
  !!  - To bool;   STACK = [0 0 0 0 0 0 0 28 1]
  @   - Reverse;   STACK = [1 28 0 0 0 0 0 0 0]
  A   - Argument;  STACK = [1 28 0 0 0 0 0 0 0 8] 
  !   - Not;       STACK = [1 28 0 0 0 0 0 0 0 0]
  @   - Reverse;   STACK = [0 0 0 0 0 0 0 0 28 1]
  *   - Multiply;  STACK = [0 0 0 0 0 0 0 0 28]
  b]  - Wrap;      STACK = [0 0 0 0 0 0 0 0 [28]]
  EZ  - Unzero;    STACK = [[28]]
  BF  - Flatten;   STACK = [28]
  #   - Sort;      STACK = [28]
  @   - Reverse;   STACK = [28]

1

R46 44 43 41字节

function(x,y=cumsum(0:x))y[(x+y)%in%y][1]

在线尝试!

具有一个强制性参数的匿名函数x;计算第一个x+1三角数作为可选参数以打出几个花括号。我choose在看到路易斯·门多的八度音阶答案之前就习惯了

我删掉了Luis Mendo的答案,但忘了在答案中使用相同的想法。





0

Clojure,74个字节

#(nth(for[t[(reductions +(range))]i t :when((set(take 1e5 t))(+ i %))]i)0)
#(nth(for[R[reductions]i(R + %(range)):when((set(R - i(range 1e5)))0)]i)0)

选择您喜欢的:)循环可能会更短...


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.