20
\$\begingroup\$

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 , 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.

\$\endgroup\$

31 Answers 31

11
\$\begingroup\$

R, 32 31 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\$.

\$\endgroup\$
8
\$\begingroup\$

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

\$\endgroup\$
3
  • \$\begingroup\$ Nice. Should the R flag be part of the language name for your answer? \$\endgroup\$ Commented Jan 1 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\$
    – lyxal
    Commented Jan 1 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\$
    – lyxal
    Commented Jan 1 at 9:30
6
\$\begingroup\$

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.

\$\endgroup\$
6
\$\begingroup\$

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
\$\endgroup\$
5
\$\begingroup\$

Vyxal R, 23 bitsv2, 2.875 bytes

¦¦c

Try it Online!

Bitstring:

10110100000101111100100

Same as my vyxal 3 answer but with the funny haha fracbyte encoding.

\$\endgroup\$
1
  • \$\begingroup\$ +1 for "funny haha fracbyte encoding" \$\endgroup\$
    – Joao-3
    Commented Jan 3 at 12:43
5
\$\begingroup\$

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

\$\endgroup\$
5
\$\begingroup\$

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$$

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 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)\$ \$\endgroup\$
    – tsh
    Commented Jan 2 at 12:25
4
\$\begingroup\$

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.

\$\endgroup\$
3
\$\begingroup\$

Uiua SBCS, 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?
\$\endgroup\$
3
\$\begingroup\$

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.

\$\endgroup\$
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\$ Commented Jan 3 at 23:04
3
\$\begingroup\$

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.

\$\endgroup\$
3
\$\begingroup\$

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!

\$\endgroup\$
4
  • \$\begingroup\$ Welcome! And this can be 57 \$\endgroup\$
    – AZTECCO
    Commented Jan 2 at 12:25
  • \$\begingroup\$ This can easily be a C function that returns through arguments. \$\endgroup\$
    – qwr
    Commented Feb 7 at 21:23
  • \$\begingroup\$ @qwr like this? i wasn't planning on switching languages, and i'm not sure if returning through the arguments is allowed \$\endgroup\$
    – nyxbird
    Commented Feb 8 at 21:04
  • \$\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
    Commented Feb 8 at 21:07
2
\$\begingroup\$

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!

\$\endgroup\$
3
  • \$\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
    Commented Jan 1 at 18:55
  • \$\begingroup\$ -2 on top of that with j*~j*~-~j/6 \$\endgroup\$
    – Jakav
    Commented Jan 1 at 19:20
  • \$\begingroup\$ @Jakav Would finally result in Albert.Lang's solution \$\endgroup\$
    – l4m2
    Commented Jan 2 at 0:22
2
\$\begingroup\$

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

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

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.

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

Perl 5 -p, 44 bytes

$i++while($;=$i*($i+1)*($i+2)/6)<$_;$_=$_==$

Try it online!

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

Haskell, 32 bytes

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.

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

Mathematica, 34 33 32 bytes

Outputs truthy/falsy reversed.

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

Try this online!

\$\endgroup\$
2
  • \$\begingroup\$ Welcome to Code Golf! Nice first answer! \$\endgroup\$
    – alephalpha
    Commented Jan 2 at 13:18
  • \$\begingroup\$ 27 bytes \$\endgroup\$
    – att
    Commented Jan 5 at 14:14
1
\$\begingroup\$

Scala 3, 41 bytes

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

Attempt This Online!

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

Charcoal, 20 bytes

NθW‹↨υ¹θ⊞υ⁺Lυ↨υ⁰⁼Συθ

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‹↨υ¹θ

Until the sum reaches n, ...

⊞υ⁺Lυ↨υ⁰

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

⁼Συθ

See whether n was reached exactly.

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

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.
\$\endgroup\$
1
\$\begingroup\$

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.

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

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.

\$\endgroup\$
2
  • \$\begingroup\$ -3 bytes \$\endgroup\$
    – jezza_99
    Commented Jan 1 at 16:06
  • \$\begingroup\$ -9 bytes \$\endgroup\$
    – Jakav
    Commented Jan 1 at 22:49
1
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ -5 bytes, uses int instead of bool to save bytes \$\endgroup\$
    – Joao-3
    Commented Jan 2 at 20:19
1
\$\begingroup\$

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)
\$\endgroup\$
1
\$\begingroup\$

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!

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

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.

\$\endgroup\$
1
  • \$\begingroup\$ +\⍣2⍤⍳ saves parens \$\endgroup\$
    – att
    Commented Jan 5 at 14:17
1
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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.

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

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!).

\$\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.