这个数字是三角形的吗?


33

挑战

给定一个正整数,请确定它是否为三角数,并相应地输出任意两个恒定且不同的值之一。

定义

三角形号码是可以被表示为连续的正整数的总和,从1开始。它们也可以与式表示的数n(n + 1) / 2,其中n一些正整数。

测试用例

真相:

1
3
6
10
15
21
55
276
1540
2701
5050
7626
18915
71253
173166
222111
303031
307720
500500
998991

虚假:

2
4
5
7
8
9
11
16
32
50
290
555
4576
31988
187394
501500
999999

规则

  • 您输入的可能是函数或程序。
  • 您可以假设输入是10 6以下的正整数。
  • 您必须选择两个不变的,不同的输出来区分这两个类别。

这是,因此每种语言中以字节为单位的最短代码获胜。





您为什么不包括零?
尼尔

1
@Neil我想尽量减少可能的边缘情况,处理零是我认为不太重要的情况之一。您是否认为零需要处理会更好?(例如,果冻答案当前失败为零)
ETHproductions '17

Answers:


21

Haskell,23个字节

编辑:

  • -1个字节:@xnor用括住了括号$

一个匿名函数,接受Int和,并返回Char

输出是'1'三角数和'0'其他数。

(!!)$show.(10^)=<<[0..]

在线尝试!

  • 用作((!!)$show.(10^)=<<[0..]) 998991
  • 生成数字1、10、100、1000,...,将其转换为字符串,然后将它们连接起来。然后索引到结果无限字符串中

    "1101001000100001000001000000...

6
一种富有想象力的方法!您可以使用保存一个字节(!!)$show.(10^)=<<[0..]
xnor

20

Python,24字节

lambda n:(8*n+1)**.5%1>0

在线尝试!

其余False为三角数输出True。检查是否8*n+1为完美正方形。不管有多大,Python都会采用完美的平方来表示精确的整数浮点数,因此没有浮点问题。


3
(1<<10000)**.5:OverflowError:int太大而无法转换为float
isaacg

@isaacg挑战不需要大的输入:“您可以假设输入是10 ^ 6以下的正整数”
trichoplax

1
@trichoplax我认为我在文本中对xnor的主张提出异议。我同意提交的内容很好。
isaacg

13

果冻,4 字节

R+\ċ

在线尝试!

怎么样?

R+\ċ - Main link: n
R    - range(n)   -> [1,2,3,...,N]
  \  - cumulative reduce by:
 +   -   addition -> [1,3,6,...,T(N)]
   ċ - count occurrences of right (n) in left -> 1 if triangular, 0 otherwise

我很惊讶累积减少量不会自动产生范围。这背后有设计选择吗?
ETHproductions '17

我不确定100%,但是我认为(至少目前如此)需要通过减少二元运算来确定范围。
乔纳森·艾伦

...实际上甚至似乎都不适用(例如thisthis。似乎quicklink实现会被覆盖,以使即使二进位运算将其定义为针对某个参数也要进行迭代,迭代器也不会产生范围。将Dennis绑定到字段这个:)
乔纳森·艾伦

@ETHproductions /\大概是第一个五年尽皆被实施中,捕食的想法投整数参数范围。
丹尼斯

13

视网膜,10字节

(^1|1\1)+$

输入为一元。输出为01

在线尝试!(作为测试套件,为了方便起见,执行十进制到一进制的转换。)

说明

这是前向引用中最基本的练习。大多数人都熟悉正则表达式中的反向引用,例如(.)\1匹配重复的字符。但是,某些更高级的样式允许您在引用的组之前或内部使用反向引用。在这种情况下,通常称为前向引用。如果重复引用,这可能很有意义。在第一次迭代中可能没有很好地定义它,但是在随后的迭代中,后面的或周围的组已经捕获了某些东西并且可以重用。

这最常用于在一元字符串上实现循环模式。在这种情况下,我们尝试将输入匹配为连续整数的和:

(        # This is group 1, which we'll repeat 1 or more times.
  ^1     #   Group 1 either matches a single 1 at the beginning of the string.
|        # or
  1\1    #   It matches whatever the previous iteration matched, plus another
         #   1, thereby incrementing our counter.
         # Note that the first alternative only works on the first iteration
         # due to the anchor, and the second alternative only works *after*
         # the first iteration, because only then the reference is valid.
)+
$        # Finally, we make sure that we can exactly hit the end of the
         # string with this process.

1
为什么不起作用(^|1\1)+$
Leaky Nun

3
@LeakyNun regex引擎进行了优化,如果空了n次,它们将停止重复一组,其中n是您使用的量词的最小值(在您的情况下为1;如果最小值为0,则无论如何将尝试一次) 。如果将更+改为{2,},则应该可以使用。这种优化可以防止无限循环,但这也是使.NET正则表达式无法单独完成图灵完成的唯一方法。
Martin Ender

这只为我节省了70个字节:codegolf.stackexchange.com/a/118387
Neil

使该74个字节,感谢\G
尼尔



7

JavaScript(ES6),30 27字节

感谢kamoroso94,节省了2个字节

f=(n,k)=>n>0?f(n+~k,-~k):!n

测试用例

非递归版本(ES7),19字节

阿德南港口的答案

x=>(8*x+1)**.5%1==0

只是在我发布我的几分钟前,现在看到您已在答案中编辑了19字节的解决方案。我应该删除我的吗?普遍接受的礼节是什么?
毛茸茸的

1
@Shaggy我认为这不是一个真正的问题。我的“主要”答案确实是递归的。
Arnauld

减少到28个字节f=(n,k=1)=>n>0?f(n-k,k+1):!n
kamoroso94

1
@ kamoroso94谢谢!更新。并且通过省略的初始化来保存第三个字节k
Arnauld

优雅地将按位NOT用作初始的增量器-undefined值;在我独立提出您先前的解决方案后,您的阅读很高兴。
apsillers

6

CJam,11个字节

ri2*_mQ_)*=

输出1为三角形,0否则为。

在线尝试!

说明

考虑输入21

ri               e# Input integer.             STACK: 21
  2*             e# Multiply by 2.             STACK: 42
    _            e# Duplicate.                 STACK: 42, 42
     mQ          e# Integer square root.       STACK: 42, 6
       _)        e# Duplicate, increment.      STACK: 42, 6, 7
         *       e# Multiply.                  STACK: 42, 42
          =      e# Equal?                     STACK: 1

6

脑爆裂,40个字节

(([{}](((()))<>))<>){<>({}({}({})))}{}{}

小麦巫师和我就这个问题进行了决斗。当我们决定发布解决方案时,我们被捆绑在42个字节上,但是我发现他的解决方案有2个字节。我们决定将其视为平局(我的解决方案如下)。

在线尝试!

说明:

# Set up the stacks like this:  -input
                                     1     -input
                                     1          1
(([{}](((()))<>))<>)                 ^

# Output 1 for triangular and 0 for non-triangular 
{<>({}({}({})))}{}{}

有关完整说明,请参见Wheat Wizard的答案


Brain-Flak,42个字节

(([({})])<>){(({}())<>{}({})){((<>))}{}{}}

产出 0\n(字面换行符)表示真实,而空字符串表示虚假。

这个想法是一直减去1再乘2再乘3直到输入。如果您按下0,则说明这是一个三角形数字,因此可以在此停下来。

在线尝试!(真实)
在线尝试!(虚假)

# Push -input on both stacks. One is a counter and the other is a running total
(([({})])<>)

# Count up from -input to 0
{
  # Push the new total which is: (counter += 1) + total (popped) + input (not popped)
  # This effectively adds 1, then 2, then 3 and so on to the running total
  (({}())<>{}({}))
  # If not 0
  {
    # Push to 0s and switch stacks to "protect" the other values
    ((<>))
  # End if
  }
  # Pop the two 0s, or empty the stack if we hit 0
  {}{}
# End loop
}

这是我发现有趣的46字节解决方案。

{<>(({}())){({}[()]<>{(<({}[()])>)}{}<>)}{}<>}

产出 0\n(字面换行符)为真,空字符串为假。

这个想法是从输入开始按连续数字递减计数,一次为1。例如input - (1) - (1,1) - (1,1,1)。每次减去时,如果还不为0,则会在堆栈上保留一个额外的值。这样,如果我们为0,并且在弹出时仍在减去,则会删除堆栈上的最后一个值。如果输入是三角数,我们将精确地以0结尾,并且不会弹出0。

在线尝试!诚实
在线尝试!虚假的

# Implicit input (call it I)

# Until we reach 0, or the stack is empty
{
  # Add 1 to the other stack and push it twice. This is our counter.
  <>(({}()))
  # While counter != 0
  {
    # counter -= 1
    ({}[()]
    # if I != 0 
    <>{
      # I -= 1, and push 0 to escape the if
      (<({}[()])>)
    # End if
    }
    # Pop from the stack with I. This is either the 0 from the if, or I
    {}
    # Get ready for next loop End while
    <>)
  # End While
  }
  # Pop the counter that we were subtracting from
  {}<>
# End Until we reach 0, or the stack is empty.
}

6

果冻,5个字节

×8‘Ʋ

在线尝试!

背景

n为输入。如果n是第k 三角数,我们有

ñ=ķķ+1个2ķ2+ķ-2ñ=0ķ=1个2-1个±1个+8ñ

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

怎么运行的

×8‘Ʋ  Main link. Argument: n

×8     Yield 8n.
  ‘    Increment, yielding 8n + 1.
   Ʋ  Test if the result is a perfect square.


5

Brain-Flak,42个字节

(([{}](<((())<>)>))<>){<>({}({}({})))}{}{}

在线尝试!

说明

该程序的目标是在两个堆栈上创建一个状态,并对两个堆栈执行恒定操作,直到其中一个堆栈为零为止,然后我们可以根据所处的堆栈进行输出。这类似于确定数字符号的程序。这些程序放在n一个堆栈上,-n上,然后添加一个堆栈并切换堆栈,直到堆栈之一为零为止。如果该数字最初为负,则第一个堆栈将为零;如果该数字为正,则其他堆栈将为零。

在这里,我们创建了两个堆栈,一个堆栈从输入中减去连续的数,另一个堆栈仅减去一个。减去连续数字的数字只会在数字为三角形的情况下终止(否则,它将只传递零并继续进入负数)。另一个总是终止于任何正数,但总是比第一个慢,因此非三角数将终止于该堆栈。

那么,我们如何设置堆栈,以便同一操作在一个堆栈上减去连续的数字,在另一个堆栈上减去一个数字?在每个堆栈上,我们在顶部都有输入,以便可以检查in,在下面有差异,在下面有差异。每次运行时,我们都将“差异之差”添加到常规“差异”中,并从输入中减去。对于检查三角形的堆栈,我们将双精度差设置为,1以便每次运行时获得连续的整数;对于其他堆栈,将其设置为,0以便我们从不更改该差,即始终保持为1。一开始如何设置堆栈,n输入在哪里:

-n  -n
 0   1
 1   0

当我们最终终止时,我们可以使用这些差异来检查我们在哪个堆栈上,我们弹出顶部的两个值,然后得到1一个三角数和0一个非三角数。


带注释的代码

(([{}](<((())<>)>))<>) Set up the stack
{                      While
 <>                    Switch stacks
 ({}({}({})))          Add bottom to second to bottom, add second to bottom to top
}                      End while
{}{}                   Pop the top two values

这也是我喜欢的50字节解决方案。

{(({}[()]))}(([[]])<>){({}{}())<>}({}{()<><{}>}{})

在线尝试!


5

Cubix,23 24 25字节

I1Wq/)s.;0..s;p-?\.+O@u

0为真,无为0。蛮族通过增加计数器,加到累加和并与输入比较来强制。 现在尝试将其安装在2x2x2立方体上。做到了!

    I 1
    W q
/ ) s . ; 0 . .
s ; p - ? \ . +
    O @
    u .

在线尝试!

  • / 面对面反映。
  • I10\ 获取整数输入,按1(计数器),按0(总和)并反映
  • +s;p-循环体。加总和和计数器,减去先前的总和,增加输入并减去
  • ? 测试减法结果
    • 对于0进行的结果笔直\.uO@反映到下表面,无操作,掉头,输出和停止。
    • 为了获得正面结果,请右转到底面并@停止
    • 对于负结果,请左移;qWs)/su减法运算,将输入置于底部,左移,调换计数器和总和,递增计数器,反射,调和总和和计数器,U形转入主循环体。

如此诱人地关闭……尽管最后一个字节将需要大量的精力和智慧。
ETHproductions '17

是的,以为我有它,但一直难以捉摸
MickyT

1
@ETHproductions找到了该字节
MickyT's

您的代码和展开的多维数据集似乎有所不同,右下角.在多维数据集上为a ,但1在代码中为a。
小麦巫师

@WheatWizard谢谢您,我这一部分
做得

4

05AB1E7 6字节

编辑:感谢@Dennis:保存了一个字节,因为我忘记了增量运算符

8*>t.ï

在线尝试!

n如果sqrt(8n + 1)是整数则为三角形

怎么运行的

8* # multiply implicit input by 8
  > # add one
   t # sqrt
    .ï # is integer

可能当时尚不可用,但现在t.ï可能会出现Ų,这是检查数字是否为正方形的内置函数。
凯文·克鲁伊森

4

Perl 6、17个字节

{$_∈[\+] 1..$_}

只需检查$_函数的输入是否等于三角加法约简的任何元素(1, 1+2, ..., 1+2+...+$_)


4

爱丽丝38 22字节

感谢Martin和Leo,节省了大量字节

/ i \ 2 * .2RE.h * -n / o @

有尾随换行符。产出1为三角形,0否则为。

在线尝试!

说明

这使用与我的CJam答案相同的方法,只是比较笨拙。以线性化形式,程序变为

i2*.2RE.h*-no@

那里io在序模式实际上是。

以输入21为例。

i         Input integer                       STACK: 21
2*        Multiply by 2                       STACK: 42
.         Duplicate                           STACK: 42, 42
2RE       Integer square root                 STACK: 42, 6
.         Duplicate                           STACK: 42, 6, 6
h         Increment                           STACK: 42, 6, 7
*         Multiply                            STACK: 42, 42
-         Subtract                            STACK: 0
n         Logical negation                    STACK: 1
o         Output integer                      STACK:
@         End program

我的第一个爱丽丝答案
路易斯·门多

1
我觉得,使用马丁的花哨控制结构之一,这大概可以减少一半……
ETHproductions '17

我也可以... :-)
路易斯·门多

我的第一个爱丽丝高尔夫:相同的代码,23个字节
Nitrodon '17

这种程序的更“标准”布局是this。也就是说,您可以摆脱堆栈上的1,而只需输出减法的逻辑取反(即...h*-no@
Leo

4

Japt10 7字节

@Luke和@ETHproductions节省了3个字节

*8Ä ¬v1

在线尝试!

说明:

*8Ä ¬v1
    ¬    // Square root of:
*8       //   Input * 8
  Ä      //   +1
     v1  // Return 1 if divisible by 1; Else, return 0

õ å+ øU

说明:

õ å+ øU
õ           // Create a range from [1...Input]
  å+        // Cumulative reduce by addition
     øU     // Does it contain the input?

在线尝试!


这个问题要求两个不变的输出。
xnor

*8Ä ¬u1 c9B(如果输入为三角形,则输出0,否则为1)
路加福音

@Luke您可以更改u1 cv1,我相信(切换输出)
ETHproductions '17

7个字节?真好!最后一次发布我自己的类似解决方案时,不知何故错过了这一点。让我知道您是否要删除它。
毛茸茸的

4

R23 19字节

Similar approach as other answers. Checks to see if 8x+1 is a perfect square.
-4 bytes thanks Giuseppe and MickyT.

!(8*scan()+1)^.5%%1

Try it online!


2
you can use ! instead of ==0
Giuseppe

This is extra nice since it's vectorized, too!
Giuseppe

1
I think you can get rid of the exterior brackets as well !(8*scan()+1)^.5%%1
MickyT

3

MATL, 5 bytes

t:Ysm

Try it online!

Explanation:

t       % Duplicate input
 :      % Range(1, input)
  Ys    % Cumulative sum. This will push the first *n* triangular numbers
    m   % ismember. Pushes true if the input is contained within the array we just pushed

I was going to post t:Ys=a. Forgot about m :-)
Luis Mendo

1
@LuisMendo I didn't know about m until I saw this answer. Funny how the two answer are almost identical :D
DJMcMayhem

3

Batch, 72 bytes

@set/aj=i=0
:l
@if %1% gtr %j% set/aj+=i+=1&goto l
@if %1==%j% echo 1

Outputs 1 on success, nothing on failure. Works for zero too, although not requested by the question for some reason.


3

JavaScript (ES7), 19 18 bytes

From my answer to a related question.

Outputs false for triangular numbers or true for non-triangular, as permitted by the OP.

n=>(8*n+1)**.5%1>0

Try It

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


I think you could save a byte with n=>(8*n+1)**.5%1>0 (which would reverse the outputs)
ETHproductions

@ETHproductions: OK, as long as you're allowing it. Is doing so normally permitted, though?
Shaggy

1
It qualifies as "two constant, distinct outputs", so yes. Other decision-problem challenges may require truthy/falsy though.
ETHproductions


3

Mathematica, 28 bytes

!Accumulate@Range@#~FreeQ~#&

I recommend replacing 7! by #. First, it's shorter; more importantly, the current solution is not correct, as it artificially imposes a limit on the size of the input it works on.
Greg Martin

1
OP says: "You may assume that the input is a positive integer under 10^6".But I like your idea and I will take it ,although mine gives the right result for every case using a list of 5040 elements but yours worst case needs a list of 999999 elements.Thanks for the tip!
J42161217

1
Oops sorry, didn't see the OP's comment! Yes, there are some "perverse" incentives in code golfing: that 1-byte savings is more important in a code-golf question than all the efficiency in the world :)
Greg Martin


3

Excel, 31 22 bytes

9 bytes saved thanks to Octopus

Outputs TRUE for triangular numbers. Else FALSE. Checks if 8*n+1 is a perfect square.

=MOD(SQRT(8*B1+1),1)=0

1
=MOD(SQRT(8*A1+1),1)=0 saves a few bytes
Octopus

2

Brachylog, 5 bytes

≥ℕ⟦+?

Try it online!

Explanation

≥ℕ⟦+?
≥ℕ     There is a number from 0 to {the input} inclusive
  ⟦    such that the range from 0 to that number
   +   has a sum
    ?  that equals the input


2

Python - 52 bytes

Note: I know that the other two Python answers are much shorter, but this is the old-school way, more of a by-hand algorithm

n=input();i=s=0
while s<n:s=(i*i+i)/2;i+=1
print s>n

2

APL (Dyalog), 6 bytes

⊢∊+\∘

Try it online!

Explanation

⊢∊+\∘
                       Creates a range from 1 to the right_argument
  +\                    Cumulative sum of this range; 1 1+2 1+2+3 .. 1+2+..+n. These are the triangular numbers
⊢∊                      Does the right argument belong to this list of integers in this cumulative sum

Outputs 0 for false and 1 for true.


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.