45
\$\begingroup\$

Challenge

Given a positive integer, determine whether it is a triangular number, and accordingly output one of any two constant, distinct values.

Definition

A triangular number is a number that can be expressed as the sum of consecutive positive integers, starting at 1. They can also be expressed with the formula \$\frac {n(n + 1)} 2\$, where \$n\$ is some positive integer.

Test cases

Truthy:

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

Falsy:

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

Rules

  • Your entry may be a function or a program.
  • You may assume that the input is a positive integer under \$10^6\$.
  • You must pick two constant, distinct outputs to distinguish the two categories.

This is , so the shortest code in bytes in each language wins.

\$\endgroup\$
12
  • 1
    \$\begingroup\$ Related, related. \$\endgroup\$ Commented May 22, 2017 at 20:27
  • \$\begingroup\$ Related OEIS sequence \$\endgroup\$
    – ovs
    Commented May 22, 2017 at 21:14
  • \$\begingroup\$ Related \$\endgroup\$
    – Shaggy
    Commented May 22, 2017 at 21:28
  • \$\begingroup\$ Why didn't you include zero? \$\endgroup\$
    – Neil
    Commented May 22, 2017 at 21:40
  • 2
    \$\begingroup\$ @Neil I wanted to minimize the number of possible edge cases, and handling zero is one of them that I felt wasn't too important. Do you think it would have been better if zero needed to be handled? (The Jelly answer currently fails on zero, for instance) \$\endgroup\$ Commented May 22, 2017 at 21:44

77 Answers 77

2
\$\begingroup\$

Fourier, 26 bytes

I~X1(&N^*N/2{X}{1~O}N=X)Oo

Try it online!

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

TI-BASIC, 10 7 bytes

-3 thanks to @lirtosiast

:not(fPart(√(8Ans+1

Takes input on X. Checks if √(8X+1) is a whole number

\$\endgroup\$
2
  • \$\begingroup\$ Why not not(fPart(√(8Ans+1? \$\endgroup\$
    – lirtosiast
    Commented Aug 25, 2017 at 0:48
  • \$\begingroup\$ @lirtosiast That'll work, thanks! \$\endgroup\$ Commented Aug 25, 2017 at 2:59
2
\$\begingroup\$

Gol><>, 12 bytes

I8*P12,X1%zh

6 bytes golfed off, courtesy of JoKing! A codebreakdown will be coming soon!

Try it online!

First version, 18 bytes

I8*P12,X1}:S(-Zh0h

I found a pretty simple formula for solving this, which helped golf this, since we are only looking to see if the number is triangular, rather than calculate it.

Link to wiki where I found the formula!

Triangular Number Formula

Code Breakdown!

I8*P              //Multiply the output by eight
    12,X          //Get the square root
        1}        //Push a value for truthy output and put it on the bottom
          :S(-    //Check to see if it is a perfect squareroot, no floating point
              Zh0h//If the difference is zero(perfect squareroot) output truthy, otherwise, push a falsey and output!

There is a way to remove 2 bytes, but it outputs the input plus one for truthy, which I don't think is to the specification of "You must pick two constant, distinct outputs to distinguish the two categories".

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ You can replace 1}:S(-Zh0h with 1%zh \$\endgroup\$
    – Jo King
    Commented Feb 14, 2019 at 4:45
  • \$\begingroup\$ A tip: You don't need to use conditionals like ?ZqQ for value checking. Just transform the values directly into 1 or 0 using comparison operators \$\endgroup\$
    – Jo King
    Commented Feb 14, 2019 at 5:07
  • \$\begingroup\$ @JoKing Thank you very much, I have made the changes and it has popped off 6 bytes! \$\endgroup\$ Commented Feb 14, 2019 at 12:10
2
\$\begingroup\$

C (gcc), 26 bytes

f(n){fmod(sqrt(8*n+1),1);}

Outputs zero for truthy and nonzero for falsy.

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Why the downvote? If it's about the output format, I haven't gotten a response back from the OP on that. \$\endgroup\$
    – S.S. Anne
    Commented Mar 28, 2020 at 23:57
  • \$\begingroup\$ Maybe the unspecified flags? \$\endgroup\$
    – Jo King
    Commented Nov 18, 2022 at 10:30
2
\$\begingroup\$

cQuents, 4 bytes

?Z+$

Try it online!

cQuents is literally made for these questions.

?    # Query (Outputs if the input is in the sequence)
 Z   # Previous term of the sequencd
  +$ # Plus the index (starts from 1)
\$\endgroup\$
2
\$\begingroup\$

Python 3.8 (pre-release), 45 40 39 bytes

lambda n:0in[n:=n+~i for i in range(n)]

Try it online!, which is a golf of this more standard

lambda n,t=0:n in[t:=t+i for i in range(n+1)]

Try it online! Not a Python winner but it showcases the := walrus operator in a scenario where it could actually be used in the real world! Hehe

\$\endgroup\$
3
  • 1
    \$\begingroup\$ A bit shorter counting downwards: TIO \$\endgroup\$
    – xnor
    Commented Mar 19, 2020 at 23:50
  • \$\begingroup\$ @xnor oh wow, that is really clever \$\endgroup\$
    – RGS
    Commented Mar 20, 2020 at 9:05
  • 1
    \$\begingroup\$ -1 because we don't need to handle zero. \$\endgroup\$
    – Bubbler
    Commented Apr 6, 2020 at 2:30
2
\$\begingroup\$

Husk, 4 bytes

±£∫N

Try it online!

Since it reqiures a constant truthy value, ±(sign) is used.

\$\endgroup\$
2
\$\begingroup\$

Regex (ECMAScript), 37 bytes

Warning: Despite this regex's small size, it contains a major spoiler. I highly recommend learning how to solve unary mathematical problems in ECMAScript regex by figuring out the initial mathematical insights independently. It's been a fascinating journey for me, and I don't want to spoil it for anybody who might potentially want to try it themselves, especially those with an interest in number theory. See this earlier post for a list of consecutively spoiler-tagged recommended problems to solve one by one.

So do not read any further if you don't want some advanced unary regex magic spoiled for you. If you do want to take a shot at figuring out this magic yourself, I highly recommend starting by solving some problems in ECMAScript regex as outlined in that post linked above.

This is the simplest natural number unary that, in order to be implemented in ECMAScript regex, absolutely requires an algorithm for generalized multiplication. This is in contrast to matching perfect squares and other powers, which can be done by dividing out prime factors individually (although the best golf is not achieved that way). Generalized multiplication can be implemented by prime factorization, and I did so on my initial try, but it takes 600+ bytes.

Remarkably, generalized multiplication can be implemented quite concisely in ECMAScript regex using the Chinese remainder theorem. The algorithm is discussed in my abundant numbers answer.

teukon posed the Triangular Numbers puzzle in 2014, after we had both figured out the best algorithm for generalized multiplication. I was not able to beat his golf on this problem; he managed to get it down to 37 bytes, but I was only able to get it down to 48 bytes. He's unlikely to ever create an account on CGCC, and I haven't been able to even get in contact with him since 2014. I feel this very elegant regex belongs on CGCC, though, and the ideas behind it were a joint effort between us, so I'm posting on his behalf:

^((((x*)x?)\3)x)(?=\4(\1*)\2*$)\1*$\5

Try it online!

^                  # N = input number
(                  # \1 = n*2-1 or n*2+1
    (              # \2 = \1-1
        (          # \3 = n-1 or n
            (x*)   # \4 = n-1
            x?
        )
        \3
    )
    x
)
(?=
    \4(\1*)\2*$    # iff \1+\4*\1 == N, then the first match here must result in \5 == 0
)
\1*$\5             # test for divisibility by \1 and for \5 == 0 simultaneously

Including zero in the "truthy" category only costs 1 byte (bringing it to 38 bytes), using ECMAScript NPCG (non-participating/unset capture group) behavior:

^((((x*)x?)\3)x)?(?=\4(\1*)\2*$)\1*$\5

Try it online!

Doing so with NPCG-independent behavior costs 3 bytes, bringing it to 40 bytes:

^((((x*)x?)\3)x)(?=\4(\1*)\2*$)\1*$\5|^$

Try it online!

Returning the triangular root

48 bytes with zero-handling, based on the 38 byte true/false version:

^(?=((((x*)x?)\3)x)?(?=\4(\1*)\2*$)\1*$\5)x?\3\4

Try it online!

46 bytes without zero-handling, based on the 37 byte true/false version:

^(?=((((x*)x?)\3)x)(?=\4(\1*)\2*$)\1*$\5)x\3\4

Try it online!

I haven't tried golfing this down yet. There may be specific golf optimizations for returning the triangular root.

\$\endgroup\$
2
\$\begingroup\$

Fourier, 24 bytes

I~_(~#^*#/2{_}{1~$}#^)$o

Based on my other answer

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Python 3, 105 bytes

import math
n=int(input(""))
if float(math.sqrt(8*n+1)).is_integer():
    print("y")
else:
    print("n")

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Your answer can be a function, so it can be lambda n:float(math.sqrt(8*n+1)).is_integer();import math. And math.sqrt can be replaced with **0.5. \$\endgroup\$
    – qwr
    Commented Dec 23, 2023 at 7:00
2
\$\begingroup\$

Desmos, 27 bytes

f(n)=0^{mod((8n+1)^{.5},1)}

Try It On Desmos!

\$\endgroup\$
2
\$\begingroup\$

05AB1E, 4 bytes

All of the following programs work:

ÅTθQ
ÅTI¢
ÅTIå
ÅTs¢
ÅTså
ÅT¹¢
ÅT¹å

Try every single one of these programs online!

ÅT is all triangular numbers \$≤\$ implicit input, θ is last element (a[-1]), Q is equality (a==b), I and ¹ are input (input()), ¢ is occurrences (a.count(b)), and å is membership (b in a).

\$\endgroup\$
2
\$\begingroup\$

TI-BASIC (TI-83/84) , 28 26 10 bytes

saved 2 bytes by using a different method

count was way off

:fPart(√(8Ans+1))=0

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Welcome to Code Golf StackExchange, and nice first answer! I don't know TI-BASIC, but it seems that it has a special way to count bytes, so your answer might be shorter than 28 bytes. \$\endgroup\$
    – alephalpha
    Commented Dec 25, 2023 at 2:00
  • \$\begingroup\$ Taking the input from a predefined variable is not allowed, but Ans is allowed \$\endgroup\$
    – MarcMush
    Commented Dec 25, 2023 at 9:37
  • \$\begingroup\$ See the other ti-basic answer \$\endgroup\$
    – MarcMush
    Commented Dec 25, 2023 at 9:38
2
\$\begingroup\$

dc, 18 bytes

Try it online!

?8*1+dvd*[0]sI=Izp

Prints 1 if triangular, 0 if not.

Explanation:

?       get input (call it x)
8*1+    let y = 8 * x + 1
d       duplicate
vd*     square root, then square (dc's sqrt has integer precision)
[0]sI=I if y == sqrt(y)^2, leave 0 on stack, otherwise leave nothing
zp      print stack depth
\$\endgroup\$
2
  • \$\begingroup\$ Welcome to Code Golf! Could you provide a link that shows the program on multiple inputs, like tio.run/#dc? \$\endgroup\$
    – Tbw
    Commented Dec 27, 2023 at 0:34
  • \$\begingroup\$ I added a tio link, but the program only takes one value at a time. \$\endgroup\$ Commented Dec 27, 2023 at 22:19
1
\$\begingroup\$

Brain-Flak, 62 bytes

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

Try it online!

Explanation

Effectively, this code starts with n and subtracts 1, 2, 3, ... n. If an intermediate result is 0, this is marked by decreasing the size of the left stack.

   (({}))                         duplicate input n
 ([      ])                       push -n as accumulator
(          <>)                    push -n on other stack as counter

{                            }    while counter is nonzero
  ({}())                          increment counter
        <>{}                      add to accumulator
            ({})                  add stored copy of n (effectively, this adds a counter that starts at 1 instead of -n)
 (              )                 push as new accumulator value
                 {(<><>)}{}       If accumulator is zero, shrink the stack by one
                           <>     switch back to right stack

<>                                move to left stack
   [[]]()()()                     3 minus height of left stack (which is 2 if n is triangular and 3 otherwise)
             <>{}                 move back to right stack and pop zero from loop
  (              )                push answer
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I ctrl-F'd for "><>"... Oh, there's already- no wait, that's Brain-Flak? \$\endgroup\$ Commented May 23, 2017 at 6:14
1
\$\begingroup\$

><>, 30 28 bytes

-2 bytes thanks to lanlock4

Assumes input is on the stack. Outputs either a 1 or 0.

0v
1<~v!?(}:{:,2*+1::+
n={<;

This was fun. I'm new to ><>, and I'd welcome any suggestions for golfing.

This starts with n=1, then continually increments n while n(n-1)/2 is less than the input number. Once the loop terminates, it prints 1 if n(n-1)/2 is equal to the input number, 0 otherwise.

\$\endgroup\$
1
  • \$\begingroup\$ If you move the +1 to the left of the < on the second line and start at n=0 instead of n=1, you can get rid of both of the spaces, like this. \$\endgroup\$
    – Not a tree
    Commented May 23, 2017 at 9:27
1
\$\begingroup\$

2Col, 8 bytes [non-competing]

*8
+1
Sq

Try it on 2Collide

Braingolf got boring so now I'm making a new language. Link leads to the current 2Col interpreter in TIO, with the above code already inserted. 3rd argument is input.

2Col is a language where each line is a 2 character expression of some form. It's what I like to call an "Accumulator-based" language. It works like Stack-based languages, except the "stack" can only contain a single item.

Explanation:

        Implicit input to Cell
*8      Multiply Cell by 8
+1      Add 1 to Cell
Sq      Return true if Cell is square number
        Implicit: Print final line's return value
\$\endgroup\$
0
1
\$\begingroup\$

C, 45 bytes

a,i;f(n){while(i<=n&&(a=i*i+i++!=2*n));a=!a;}

Try it online.

Explanation:

a,i; - data definition with no type or storage class is allowed in C (gives a warning). Doesn't work in C++ though.
f(n) - This behavior(parameter without type - by default assigned an integer type) is to provide backwards compatibility with older K&R version of C.
while() - loop is self explanatory
a=!a; - the return value of the function should be in "eax" register, but it is often also used as scratch register by calee. So we do a negation operation to store the answer in the eax which gets returned. 
\$\endgroup\$
1
\$\begingroup\$

CJam, 10

ri8*)_mQ%!

Try it online

It checks if 8*n+1 is divisible by its integer square root.

\$\endgroup\$
1
  • \$\begingroup\$ Interesting variant of the 8*n+1 method. In general this divisibility check tells if a number is of the form k^2, k^2+k or k^2+2*k, but a number of the form 8*n+1 can only be the first case. \$\endgroup\$ Commented Oct 26, 2017 at 19:30
1
\$\begingroup\$

Pyt, 5 bytes

←Đř△∈

Explanation:

←                 get input
 Đ                duplicate input (on stack twice)
  ř               push [1,...,input] onto stack
   △              calculate the kth triangle number for each element k in the array
    ∈             check if input is in array of triangle numbers


Longer but faster way, 9 bytes

←Đ2*√⌈ř△∈

Explanation:

←                     get input
 Đ                    duplicate input (on stack twice)
  2*                  double input
    √⌈                ceiling of the square root
      ř               push [1,...,value from previous step] onto stack
       △              calculate the kth triangle number for each element k in the array
        ∈             check if input is in array of triangle numbers
\$\endgroup\$
1
\$\begingroup\$

APL(NARS) 12 chars, 24 bytes

{0=1∣√1+8×⍵}

It is done seen(copy) some other solution... it seems {1∣⍵} it is 0 when ⍵ is one int decimal with 0 digits afther the "." test:

  f←{0=1∣√1+8×⍵}
  {⍞←{1=f ⍵:' ',⍵⋄⍬}⍵⋄⍬}¨0..200
 0  1  3  6  10  15  21  28  36  45  55  66  78  91  105  120  136  153  171  190  
  

but i remember i wrote the solution to this a little +long, some time ago...

\$\endgroup\$
1
\$\begingroup\$

cQuents, 4 bytes

?Z+$

Try it online!

Explanation

?Z+$
        Given input n,
?       Mode query: output true if n is in sequence, false if n is not in sequence
        Each term in the sequence equals
 Z      Previous term
  +                   +
   $                    current index (1-indexed)
\$\endgroup\$
1
\$\begingroup\$

PowerShell, 36 bytes

for(;$args-gt$s){$s+=++$i}$s-in$args

Try it online!

This script is 6 bytes longer than the briantist's solution. The script works with any [long] (except for 0) and calculates only what is needed.

\$\endgroup\$
1
\$\begingroup\$

tinylisp, 65 60 bytes

(d T(q((N I)(i(l N 0)0(a(e N 0)(T(s N I)(a I 1)
(q((N)(T N 1

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Scala, 24 bytes

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

Same approach as taken by many others here: check whether \$\sqrt{8n+1}\$ is an integer (via fractional modulo)

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Vyxal, 3 bytes

ɾ¦c

Try it Online! or Try a Test Suite Online!

Can be 2 bytes with the R flag.

The power of automatically swapping arguments based on types.

Explained

ɾ¦c
ɾ    # The range [1..n]
 ¦  # Cumulative sums of that - this creates a list of the first n triangular numbers, which is guaranteed to include at least one number bigger than the input. 
  c # is the input in that list? The arguments popped are [input, triangles] but Vyxal is smart enough to realise that because a list will never be in a number, it can swap the arguments and perform the membership test. 
\$\endgroup\$
1
\$\begingroup\$

Nekomata + -e, 4 bytes

8*→√

Attempt This Online!

8*→√
8*    Multiply the input by 8
  →   Increment
   √  Check if it's a perfect square

Nekomata + -e, 4 bytes

R∫$Ĩ

Attempt This Online!

R∫$Ĩ
R     Range from 1 to input
 ∫    Cumulative sum
  $Ĩ  Check if it contains the input
\$\endgroup\$
1
\$\begingroup\$

R (4.1+), 20 bytes

R has a vectorized cumsum(), which can come in handy for time series data.

\(x)x%in%cumsum(1:x)

Attempt This Online!

\$\endgroup\$
1
\$\begingroup\$

Haskell, 27 bytes

This is my first time using Haskell rather than SML (I couldn't find a scan function), so I don't know if this is a valid answer, but it is a valid function in the interpreter.

\x->elem x(scanl(+)0[1..x])
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.