# Is this number tetrahedral?

Happy New Year 2024!

2024 is a tetrahedral number. A tetrahedral number is a number that can be represented in the form $$\n(n+1)(n+2)/6\$$ for some positive integer $$\n\$$. Or, equivalently, they are the sum of the first $$\n\$$ triangular numbers. They are also the number of objects in a triangular pyramid which has $$\n\$$ objects on each of its edges.

For example, $$\10\$$ is a tetrahedral number because $$\10 = \frac{3 \times 4 \times 5}{6}\$$.

Here are the first few tetrahedral numbers:

1, 4, 10, 20, 35, 56, 84, 120, 165, 220, 286, 364, 455, 560, 680, 816, 969, 1140, 1330, 1540, 1771, 2024, ...


This is sequence A000292 in the OEIS.

Given a positive integer $$\n\$$, determine whether $$\n\$$ is a tetrahedral number.

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

This is also a , so you may use your language's convention for truthy/falsy (swapping truthy and falsy is allowed), or use two distinct, fixed values to represent true or false.

# R, 3231 29 bytes

function(n)n%in%choose(3:n,3)


Try it online!

Based on the observation on wiki or OEIS that $$\Te_n={{n+2}\choose{3}}\$$; : ranges downwards for the case of $$\n=1\$$.

# Vyxal 3R, 3 bytes

@@c


Try it Online! (link is to literate version)

Simply cumulative sum twice, and check if the input is in that.

R flag casts num to range for cumsum

• Nice. Should the R flag be part of the language name for your answer? Jan 1 at 8:56
• @NickKennedy it's the result of a new website for the new language - there'll be things I've forgotten like the part that includes flags in the submission :p Jan 1 at 9:27
• On closer inspection, it was a bug where for some reason, using literate mode completely wiped all flags in the template instead of just removing the literate mode flag. A very silly bug Jan 1 at 9:30

# Retina 0.8.2, 26 bytes

.+
$* (^(1)|(?<2>1\2)\1)+$


Try it online! Link includes test cases. Explanation: The first stage just converts to unary; the second stage adds successive triangular numbers to see if this will exactly consume the unary number. The ?<2> syntax reuses capturing group 2; the equivalent in Perl is to use alternative capture group numbering:

# Perl 5-p, 33 bytes

$_=(1x$_)=~/((?|^(1)|(1\2)\1))+$/  Try it online! Link includes test cases. # MATL, 6 bytes t:tY+m  Try at MATL online! ### How it works This uses the fact (see OEIS) that tetrahedral numbers are the convolution of the natural numbers with themselves It suffices to compute the convolution of the finite sequence 1, 2, ..., n with itself. Also, it is not necessary to discard the "transient" (non-valid part) at the end of the convolution result, because all the values there exceed n and thus cannot cause false positives. t % Implicit input: n. Duplicate : % Range: gives [1 2 ... n] t % Duplicate Y+ % Convolution m % Ismember. Implicit output  # VyxalR, 23 bitsv2, 2.875 bytes ¦¦c  Try it Online! Bitstring: 10110100000101111100100  Same as my vyxal 3 answer but with the funny haha fracbyte encoding. • +1 for "funny haha fracbyte encoding" Jan 3 at 12:43 # Ruby, 41 bytes ->n{n*=6;a=(n**3**-1).to_i;n==a*-~a*a+=2}  Try it online! Finds the cube root of n*6 rounded down,then applies the formula a*(a+1)*(a+2) to see if this equals n*6 # JavaScript (ES7), 28 bytes -2 thanks to @tsh Returns a falsy value for tetrahedral. n=>(n*=6)+(n**=1/3,~n)**3-~n  Try it online! ### Method Computes: $$k=\left\lfloor (6n)^{1/3}\right\rfloor$$ And tests whether: $$(k+1)^3-k-1=6n$$ • Since swap truthy falsy is allowed, you can change == into -. Also, this is 28 bytes n=>(n*=6)+(n**=1/3,~n)**3-~n which use $k(k+1)(k+2)=(k+1)^3-(k+1)$ – tsh Jan 2 at 12:25 # Jelly, 4 bytes RÄÄċ  Try it online! A monadic link taking an integer and returning 1 for tetrahedral and 0 for not. Similar to many of the other answers: range, cumsum, cumsum, count. # UiuaSBCS, 10 bytes ∊:\+\++1⇡.  Try it! Port of lyxal's Vyxal 3 answer. ∊:\+\++1⇡. . # duplicate ⇡ # range +1 # increment \+\+ # cumulative sum twice ∊: # is the input in this?  # Python, 42 bytes lambda n:n*6in(y**3-y for y in range(n+2))  Attempt This Online! Returns True/False. Saves a few bytes by shifting the closed formula by 1. • I was about to suggest the improvement of shifting the closed formula on Joao's answer (which I somehow saw first), but I somehow missed the exponentiation trick. Jan 3 at 23:04 # TI-BASIC, 14 bytes max(Ans=cumSum(cumSum(cumSum(1 or rand(Ans  Takes input in Ans. Works on numbers that are within the list size limit. ### 20 bytes Input N int(³√(6N Ans³+3Ans²+2Ans=6N  Based on Arnauld's answer. # C++, 63 57 bytes (-6 bytes thanks to AZTECCO) [](int n){for(int i=n+3;i--;)n*=n!=-~i*i*~-i/6;return n;}  Try it online! This swaps truthy/falsy, so it returns an integer greater than 0 for non-tetrahedral numbers, and 0 for tetrahedral numbers. 63 byte version: [](int n){for(int i=n+2;i-->0;)if(n==-~i*i*~-i/6)n=0;return n;}  Try it online! • Welcome! And this can be 57 Jan 2 at 12:25 • This can easily be a C function that returns through arguments. – qwr Feb 7 at 21:23 • @qwr like this? i wasn't planning on switching languages, and i'm not sure if returning through the arguments is allowed Feb 8 at 21:04 • Yes there's some meta post about it. And you can define C functions instead of full programs. In C++ you have anonymous functions as you did too. – qwr Feb 8 at 21:07 # Python 3, 49 bytes lambda x:any(x==n*-~n*(n+2)/6for n in range(x+1))  Try it online! No extra work, just the original formula # Python 3, 47 bytes swapping T/F lambda x:all(x+n*~n*(n+2)/6for n in range(x+1))  Try it online! • You can save two bytes from the first version with lambda n:n in[j*-~j*(j+2)/6for j in range(n+1)] Jan 1 at 18:55 • -2 on top of that with j*~j*~-~j/6 Jan 1 at 19:20 • @Jakav Would finally result in Albert.Lang's solution – l4m2 Jan 2 at 0:22 # Desmos, 31 bytes f(k)=∏_{n=1}^k(6k-nnn-3nn-2n)  Try It On Desmos! Try It On Desmos! - Prettified Returns 0 if it is a tetrahedral number, otherwise it returns a non-zero integer. For 5 more bytes, you can make it return 0 if it is a tetrahedral number, and 1 otherwise: ### 36 bytes f(k)=∏_{n=1}^ksgn(6k-nnn-3nn-2n)^2  Try It On Desmos! Try It On Desmos! - Prettified # Haskell + hgl, 12 bytes e*^xc scp<e0  Attempt This Online! ## Explanation • e0 integers from 0 to the input • xc scp perform cumulative sums twice • e determine if the input is an element. ## Reflection It is infuriating I don't have a way to check for membership in an infinite monotonic list. I would have sworn I had implemented it, but I've spent a long time looking and I can't find it. It wouldn't save bytes here, in fact if it were 3 bytes it would make this longer by a byte, but it should exist because it will be useful in the future. # Perl 5-p, 44 bytes $i++while($;=$i*($i+1)*($i+2)/6)<$_;$_=$_==$


Try it online!

• Ah, -l, that's how it's done (updates his 33 byte Perl 5 -p answer).
– Neil
Jan 1 at 8:42
• 38 bytes Try it online! Jan 4 at 16:30

f n=elem(6*n)[k^3-k|k<-[1..n+1]]


Try it online!

Check whether $$\6n\$$ is of the form $$\k^3-k\$$.

32 bytes

q=scanl1(+)
f n=elem n$q$q[1..n]


Try it online!

Using the cumulative-sum-twice method from other answers.

# Mathematica, 3433 32 bytes

Outputs truthy/falsy reversed.

k^3-k-6#/.k->⌊(6#)^(1/3)⌋+1&


Try this online!

• Welcome to Code Golf! Nice first answer! Jan 2 at 13:18
• 27 bytes
– att
Jan 5 at 14:14

# Scala 3, 41 bytes

x=>(0 to x).exists(n=>x==n*(n+1)*(n+2)/6)


Attempt This Online!

# Charcoal, 20 bytes

ＮθＷ‹↨υ¹θ⊞υ⁺Ｌυ↨υ⁰⁼Συθ


Try it online! Link is to verbose version of code. Outputs a Charcoal boolean, i.e. - for tetrahedral, nothing if not. Explanation:

Ｎθ


Input n.

Ｗ‹↨υ¹θ


Until the sum reaches n, ...

⊞υ⁺Ｌυ↨υ⁰


... push successive triangular numbers to the predefined empty list.

⁼Συθ


See whether n was reached exactly.

# x86 32-bit machine code, 11 bytes

99 31 C9 01 CA 41 29 D0 77 F9 C3


Try it online!

Following the regparm(1) calling convention, this function takes a number in EAX and returns a number in EAX, which uses reversed truthy/falsy – it is 0 for tetrahedral numbers and nonzero otherwise.

In assembly:

f:  cdq             # Set EDX to 0 by sign-extending EAX.
xor ecx, ecx    # Set ECX to 0.
r:  add edx, ecx    # Add ECX to EDX. EDX will run through the triangular numbers.
inc ecx         # Add 1 to ECX.
sub eax, edx    # Subtract EDX from EAX.
ja r            # Jump back, to repeat, if EAX remains positive.
ret             # Return.


# Raku, 48 bytes

->\a{^∞ .map(->\n{(n**3-n)/6}).first(*>=a)-a};


Attempt This Online!

Generate the sequence itself until it reaches a value greater than or equal to the input. Then return the difference, i.e., return 0 if it hits the input, and a positive integer otherwise; True/False is therefore swapped.

# Python, 80 64 55 51 47 45 bytes

lambda x:x*6in[k*~k*~-~k for k in range(x+1)]


Attempt This Online!

Based off of Aiden Chow's Desmos answer.

• -3 bytes Jan 1 at 16:06
• -9 bytes Jan 1 at 22:49

# Go, 80 75 bytes

func(x int)int{for i:=1;i<=x;i++{if 6*x==i*(i+1)*(i+2){return 1}}
return 0}


Attempt This Online!

Loops over all numbers from $$\1\$$ to $$\x\$$ inclusive and sees if $$\6x = i(i+1)(i+2)\$$.

-5 from Joao-3 by using int as the return type instead.

• -5 bytes, uses int instead of bool to save bytes Jan 2 at 20:19

# 05AB1E, 7 bytes

LηOηOIå


Explanation:

L        # Push a list in the range [1, (implicit) input]
ηOηO    # Cumulative sum twice:
η       #  Get the prefixes of this list
O      #  Sum each prefix
ηO    #  And again
Iå  # Check if the input is in this list
# (which is output implicitly as result)


# PowerShell, 76 bytes

$a=$b=1;while($b-ge1){$b=$_*6/$a/($a+1)/($a+2);if($b-eq1){return !0};$a++}!1


Try it online!

# APL(Dyalog Unicode), 10 98 bytes SBCS

⊢∊+\⍣2⍤⍳


Try it on APLgolf!

-1 byte thanks to att.

A tacit function which takes an integer on the right and returns 1 if tetrahedral and 0 if not. Same method as the Vyxal and Uiua answers.

⊢∊+\⍣2⍤⍳­⁡​‎‎⁪⁡⁪⁠⁪⁢⁤⁪‏‏​⁡⁠⁡‌⁢​‎‎⁪⁡⁪⁠⁪⁤⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁡⁪‏‏​⁡⁠⁡‌⁣​‎‎⁪⁡⁪⁠⁪⁢⁢⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁣⁪‏‏​⁡⁠⁡‌⁤​‎‎⁪⁡⁪⁠⁪⁡⁪‏⁠‎⁪⁡⁪⁠⁪⁢⁪‏‏​⁡⁠⁡‌­
⍤⍳  # ‎⁡range, then
+\      # ‎⁢cumulative sums,
⍣2    # ‎⁣twice
⊢∊        # ‎⁤input is member
💎


Created with the help of Luminespire.

• +\⍣2⍤⍳ saves parens
– att
Jan 5 at 14:17

# APL(NARS), 64 chars

r←B w;y;z
y←⌈3√w←w×6⋄r←0⋄→3
y-←1
→2×⍳w<z←y×(y+1)×y+2
→0×⍳w>z⋄r←1


9+17+4+19+11+4=64

f(y)=y×(y+1)×(y+2)=y^3+3y^2+2y is a crescent function and from y0=⌈(6w)^(1/3) => (y0)^3≥6w =>(y0)^3+3(y0)^2+2(y0)>6w so it is possible begin the loop in that point y0 and decrease y0 until (y0)^3+3(y0)^2+2(y0)≤6w

     a⊂⍨B¨a←⍳123
1  4  10  20  35  56  84  120


it seems is possible to use big rational and big float too

      B 45487864677774111x
0
B 45487864677774111x×(45487864677774111x+1)×(45487864677774111x+2)÷6
1


# dc, 50 bytes

[1pq]st[0pq]sf[1+dd1+d1+**6/dln=tln<flxx]sx?sn0lxx


Try it online!

This solution outputs 1 for truthy, and 0 for falsy.

# Rattle, 27 26 bytes

|r[=#-s+2*~*#/6[\=1q]]3=


Try it Online!

Outputs 1 if the number is tetrahedral, 0 otherwise.

# Explanation

|                    take input
r                  set input to "\" (variable)
[ ... ]3         loop int("3"+str(N)) times where N is the input. The 3 catches the edge case of 1.

=#                   set the top of the stack to i, where i is the loop count
-                  decrement
s                 save to memory
+2               increment by 2
*~             multiply by the value in memory (performing (i-1)(i+1))
*#           multiply by i to obtain (i-1)(i)(i+1), effectively the same
as n(n+1)(n+2) but with shifted indices
/6         divide by 6
[\...]   if equal to "\" (the original input)
=1     set the top of the stack to 1
q    quit and implicitly print the top of the stack
=                    if the loop exits without quitting, the number is not tetrahedral
(set top of stack to 0 then print implicitly)


There may be a way to get this shorter. I might come back later to try to get the byte count down (someone else should try too!).