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.
Task
Given a positive integer \$n\$, determine whether \$n\$ is a tetrahedral number.
This is code-golf, so the shortest code in bytes in each language wins.
This is also a decision-problem, 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.
31 Answers 31
R, (削除) 32 (削除ここまで) (削除) 31 (削除ここまで) 29 bytes
function(n)n%in%choose(3:n,3)
Based on the observation on wiki or OEIS that \$Te_n={{n+2}\choose{3}}\$; : ranges downwards for the case of \$n=1\$.
Vyxal 3 R, 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
-
\$\begingroup\$ Nice. Should the R flag be part of the language name for your answer? \$\endgroup\$Nick Kennedy– Nick Kennedy2024年01月01日 08:56:28 +00:00Commented Jan 1, 2024 at 8:56
-
\$\begingroup\$ @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 \$\endgroup\$2024年01月01日 09:27:13 +00:00Commented Jan 1, 2024 at 9:27
-
1\$\begingroup\$ 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 \$\endgroup\$2024年01月01日 09:30:53 +00:00Commented Jan 1, 2024 at 9:30
Retina 0.8.2, 26 bytes
.+
$*
(^(1)|(?<2>12円)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)|(12円)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
Vyxal R, 23 bitsv2 , 2.875 bytes
¦¦c
Bitstring:
10110100000101111100100
Same as my vyxal 3 answer but with the funny haha fracbyte encoding.
-
\$\begingroup\$ +1 for "funny haha fracbyte encoding" \$\endgroup\$Joao-3– Joao-32024年01月03日 12:43:33 +00:00Commented Jan 3, 2024 at 12:43
Ruby, 41 bytes
->n{n*=6;a=(n**3**-1).to_i;n==a*-~a*a+=2}
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
Method
Computes:
$$k=\left\lfloor (6n)^{1/3}\right\rfloor$$
And tests whether:
$$(k+1)^3-k-1=6n$$
-
1\$\begingroup\$ Since swap truthy falsy is allowed, you can change
==into-. Also, this is 28 bytesn=>(n*=6)+(n**=1/3,~n)**3-~nwhich use \$k(k+1)(k+2)=(k+1)^3-(k+1)\$ \$\endgroup\$tsh– tsh2024年01月02日 12:25:31 +00:00Commented Jan 2, 2024 at 12:25
Jelly, 4 bytes
RÄÄċ
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.
Uiua SBCS , 10 bytes
∊:\+\++1⇡.
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))
Returns True/False. Saves a few bytes by shifting the closed formula by 1.
-
\$\begingroup\$ 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. \$\endgroup\$Karl Knechtel– Karl Knechtel2024年01月03日 23:04:43 +00:00Commented Jan 3, 2024 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(3√(6N
Ans3+3Ans2+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;}
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;}
-
-
\$\begingroup\$ This can easily be a C function that returns through arguments. \$\endgroup\$qwr– qwr2024年02月07日 21:23:37 +00:00Commented Feb 7, 2024 at 21:23
-
-
\$\begingroup\$ 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. \$\endgroup\$qwr– qwr2024年02月08日 21:07:53 +00:00Commented Feb 8, 2024 at 21:07
Python 3, 49 bytes
lambda x:any(x==n*-~n*(n+2)/6for n in range(x+1))
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))
-
\$\begingroup\$ You can save two bytes from the first version with
lambda n:n in[j*-~j*(j+2)/6for j in range(n+1)]\$\endgroup\$Jakav– Jakav2024年01月01日 18:55:39 +00:00Commented Jan 1, 2024 at 18:55 -
\$\begingroup\$ -2 on top of that with
j*~j*~-~j/6\$\endgroup\$Jakav– Jakav2024年01月01日 19:20:59 +00:00Commented Jan 1, 2024 at 19:20 -
\$\begingroup\$ @Jakav Would finally result in Albert.Lang's solution \$\endgroup\$l4m2– l4m22024年01月02日 00:22:29 +00:00Commented Jan 2, 2024 at 0:22
Desmos, 31 bytes
f(k)=∏_{n=1}^k(6k-nnn-3nn-2n)
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
Haskell + hgl, 12 bytes
e*^xc scp<e0
Explanation
e0integers from 0 to the inputxc scpperform cumulative sums twiceedetermine 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.
-
\$\begingroup\$ Ah,
-l, that's how it's done (updates his 33 byte Perl 5-panswer). \$\endgroup\$Neil– Neil2024年01月01日 08:42:43 +00:00Commented Jan 1, 2024 at 8:42 -
\$\begingroup\$ 38 bytes Try it online! \$\endgroup\$Nahuel Fouilleul– Nahuel Fouilleul2024年01月04日 16:30:11 +00:00Commented Jan 4, 2024 at 16:30
Haskell, 32 bytes
f n=elem(6*n)[k^3-k|k<-[1..n+1]]
Check whether \6ドルn\$ is of the form \$k^3-k\$.
32 bytes
q=scanl1(+)
f n=elem n$q$q[1..n]
Using the cumulative-sum-twice method from other answers.
Mathematica, (削除) 34 (削除ここまで) (削除) 33 (削除ここまで) 32 bytes
Outputs truthy/falsy reversed.
k^3-k-6#/.k->⌊(6#)^(1/3)⌋+1&
-
\$\begingroup\$ Welcome to Code Golf! Nice first answer! \$\endgroup\$alephalpha– alephalpha2024年01月02日 13:18:42 +00:00Commented Jan 2, 2024 at 13:18
-
Charcoal, 20 bytes
NθW‹↨υ1θ⊞υ+Lυ↨υ0=Συθ
Try it online! Link is to verbose version of code. Outputs a Charcoal boolean, i.e. - for tetrahedral, nothing if not. Explanation:
Nθ
Input n.
W‹↨υ1θ
Until the sum reaches n, ...
⊞υ+Lυ↨υ0
... 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
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};
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)]
Based off of Aiden Chow's Desmos answer.
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}
Loops over all numbers from \1ドル\$ to \$x\$ inclusive and sees if \6ドルx = i(i+1)(i+2)\$.
-5 from Joao-3 by using int as the return type instead.
05AB1E, 7 bytes
LηOηOIå
Try it online or verify the first 100 test cases.
Explanation:
Similar as other answers.
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
APL(Dyalog Unicode), (削除) 10 9 (削除ここまで)8 bytes SBCS
⊢∊+\⍣2⍤⍳
-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.
-
\$\begingroup\$
+\⍣2⍤⍳saves parens \$\endgroup\$att– att2024年01月05日 14:17:55 +00:00Commented Jan 5, 2024 at 14:17
APL(NARS), 64 chars
r←B ×ばつ⍳w&l×ばつ(y+1)×ばつ⍳w>z⋄r←1
9+たす17+たす4+たす19+たす11+たす4=わ64
f(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+1)×ばつ(45487864677774111x+2)÷6
1
dc, 50 bytes
[1pq]st[0pq]sf[1+dd1+d1+**6/dln=tln<flxx]sx?sn0lxx
This solution outputs 1 for truthy, and 0 for falsy.
Rattle, (削除) 27 (削除ここまで) 26 bytes
|r`[=#-s+2*~*#/6[\=1q]]3`=
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!).