N-dimensional pyramid numbers [duplicate]

Given two inputs, a number n and a dimension d, generate the nth d-dimensional pyramid number.

That was confusing, let me try again.

For d = 1, the numbers start 1,2,3,4,5 and is the number of points in a line n points long.

For d = 2, the numbers start 1,3,6,10,15 and is the number of points in a triangle with side length n, also known as the triangle numbers e.g.

0
0 0
0 0 0
0 0 0 0

For d=3, the numbers start 1,4,10,20,35 and is the number of points in a pyramid of side n. For d=4, it's a 4-d pyramid, and so on.

Beyond this, visualization gets a bit tricky so you will have to use the fact that the nth d-dimensional pyramid number is equal to the sum of the first n d-1-dimensional pyramid numbers.

For example, the number of dots in a 3-d pyramid of side 5 is the sum of the first 5 triangle numbers: 1+3+6+10+15 = 35.

You can expect reasonable input (within your languages boundaries), although Standard loopholes apply. No builtins explicitly for this purpose (looking at you, Mathematica)

Numbers are 1-indexed, unless you specify otherwise.

Example recursive code in Javascript:

function pyramid(dim,num){                          //declare function
if(dim == 0){                                     //any 0-dimensional is a single point, so return 1
return 1;
} else {                                          //otherwise
function numbersUpTo(x){                        //helper function to get the numbers up to x
if(x==0){                                     //no numbers up to 0
return [];
} else {                                      //otherwise recurse
return [x].concat(numbersUpTo(x-1));
}
}
var upto = numbersUpTo(num).map(function(each){ //for each number up to num
return pyramid(dim-1,each);                   //replace in array with pyramid(dimension - 1,the number)
});
return upto.reduce((a,b)=>a+b);                 //get sum of array
}
}

This is code-golf, so fewest bytes wins.

• Welcome to Code Golf! As it is, this seems like a reasonably well-written challenge. However, in future, I'd recommend posting in the Sandbox to get feedback first. Feb 18 '21 at 9:44
• Isn't it the same as nCr(n+d, d)? If so, I'm afraid it's a duplicate of existing nCr challenges. Feb 18 '21 at 10:04
• @Bubbler it's actually nCr(n+d, d-1) Feb 18 '21 at 10:14
• If you index n from 0 and d from 1, then @Bubbler's formula is correct. Feb 18 '21 at 13:01
• @pxeger xigoi is indeed correct: it's nCr(n+d-1, d). Feb 18 '21 at 13:55

JavaScript (ES6), 24 bytes

Expects (n)(d).

n=>g=d=>d?n++/d*g(d-1):1

Try it online!

• For posterity, since Arnauld's edits fell within the grace period: 36 34 Feb 18 '21 at 10:08
• @pxeger The 34-byte version was really silly since k is not used anymore. :-p Feb 18 '21 at 10:10

APL(Dyalog Unicode), 7 6 bytes SBCS

⊢!1-⍨+

-1 from rak1507.

A train submission which takes n on the left and d on the right.

Uses the combination based formula mentioned in the question comments.

1-indexed.

Explanation

⊢!1-⍨+
+ n + d
1-⍨  - 1
!     choose
⊢      d
• ⊢!1-⍨+ is 6 bytes Feb 18 '21 at 13:13

Jelly, 3 bytes

+’c

Try it online!

Accepts n as the first argument and d as the second argument. Uses the formula $$n+d-1 \choose d$$

Explanation

+     Sum
’    Decrement
c   Combinations with the right argument

Jelly, 8 bytes

’çⱮSɗṛ’?

Try it online!

Accepts d as the first argument and n as the second argument. Uses the algorithm described in the challenge.

Explanation

?   If
’    d-1 ≠ 0
ɗ      then (
’            d-1
Ɱ            with each [1..n] as the right argument
S         Sum
ɗ      )
ṛ     else n

For some reason, this does not work with ß instead of ç. It would be nice if someone explained why.

[!<:@+

Try it online!

Whispers v2, 52 49 bytes

> Input
> Input
>> 1+2
>> ≺3
>> 4C2
>> Output 5

Try it online!

Inputs the numbers from STDIN.

-3 bytes from Michael Chatiskatzi.

If floating point output is not allowed, then 63 bytes.

• 49 bytes if you use for decrementing. Feb 21 '21 at 9:25

Perl 5, 41 bytes

sub f{($n,$d)=@_;$d?$n/$d*f($n+1,$d-1):1} Try it online! Influenced by Arnaulds javascript answer.$D=$_,print"d=$D:   ".join(" ",map f($_,$D), 1..10)."\n" for 1..4;

d=1:   1 2 3 4 5 6 7 8 9 10
d=2:   1 3 6 10 15 21 28 36 45 55
d=3:   1 4 10 20 35 56 84 120 165 220
d=4:   1 5 15 35 70 126 210 330 495 715
• You can save 4 bytes by using named parameters tio.run/… Feb 20 '21 at 18:29
• Nice tip. But not sure if the 20 bytes in -Mfeature+signatures should be added. Maybe the Perl7 initiative will make such signatures available by default. perl.com/article/announcing-perl-7 Feb 21 '21 at 20:59

Wolfram Language (Mathematica), 17 bytes

Binomial[##-1,#]&

Try it online!

The boring answer. Input [d, n].

29 bytes

Nest[Tr@*Array~Curry~2,1&,#]&

Try it online!

Input [d][n].

Returns the d-pyramid function, constructed using the given recursive definition. Call it on n for the nth d-pyramid number.

0#n=1
d#n=(d-1)#(n+1)*n/d

Try it online!

This was my old solution, same idea, but much longer, 37 bytes

a%b=product[a+1..b-1]
d#n=d%(n+d)/0%n

Try it online!

Julia, 26 22 bytes

d>n=d<1||sum(~-d.>1:n)

Try it online!

MathGolf, 8 bytes

r+k╒m╠ε*

First input $$\d\$$ as an integer, second input $$\n\$$ as a float.

Try it online.

Explanation:

r         # Push a list in the range [0, first (implicit) input d)
+        # Add the second (implicit) input n to each: [n,n+1,...,n+d-1]
k       # Push the first input d again
╒      # Pop and push a list in the range [1,d]
m╠    # Divide the values at the same positions from one another:
#  [n/1,(n+1)/2,...,(n+d-1)/d]
ε*  # Take the product (reduce by multiplying)

Python 3, 56 55 51 bytes

Saved a byte thanks to Kevin Cruijssen!!!
Saved 4 bytes thanks to ovs!!!

f=lambda n,d:d<1or sum(f(i+1,d-1)for i in range(n))

Try it online!

• 51 bytes
– ovs
Feb 18 '21 at 11:42
• @ovs You took my brains to another dimension - thanks! :D Feb 18 '21 at 12:05

05AB1E, 97 4 bytes

+<Ic

$$\a(n,d) = {n+d-1\choose d}\$$

The inputs are in the order $$\n,d\$$.

The inputs are in the order $$\d,n\$$ and the output is a float.

Equal-bytes alternative by porting @Razetime's APL answer:

LIGηO}θ

The inputs are in the order $$\n,d\$$.

Explanation:

+        # Add the two (implicit) inputs together
<       # Decrease it by 1
I      # Push the second input d
c     # Get the number of combinations / the binomial coefficient: n+d-1 choose d
# (after which it is output implicitly as result)

L        # Push a list in the range [1, first (implicit) input d]
©       # Store it in variable ® (without popping)
<      # Decrease each by 1 to make the range [0,d)
+     # Add the second (implicit) input-integer n to each: [n,n+1,...,n+d-1]
®    # Push list [1,d] from variable ® again
/   # Divide the items at the same positions in the two lists:
#  [n/1,(n+1)/2,...,(n+d-1)/d]
P  # Take the product of this list
# (after which it is output implicitly as result)

L        # Push a list in the range [1, first (implicit) input n]
IG      # Loop the second input d - 1 amount of times:
η     #  Get the prefixes of the current list
O    #  And sum each prefix together
}θ     # After the loop: pop and leave just the last item
# (after which it is output implicitly as result)

d#n=sum\$iterate(scanl(+)0)[1..n]!!(d-1)

Try it online!

Rust, 63 58 bytes

|n,d|(n..=n+d-1).product::<u32>()/(1..=d).product::<u32>()

Try it online! (with calling code)

Wolfram Language (Mathematica), 36 35 bytes

-1 byte thanks to att!

Last@Nest[Accumulate,1~Table~#,#2]&

Try it online!

Just to prove that Mathematica can do things without builtins! One nice thing about this function is that it calculates the pyramidal numbers exactly according to the definition, by summing (using Accumulate) over pyramidal numbers of one dimension less (hence recursively starting from the 0-dimensional pyramidal numbers, here generated as an array of 1s of the correct length, using 1&~Array~#).

• Nice! Mathematica has bultins for practically every purpose, so nice job not using them! Feb 19 '21 at 8:08
• 35 bytes
– att
Feb 20 '21 at 3:33
• Ah yes, I forget that Table can do this, thanks :) Feb 20 '21 at 7:54

Python 3, 33 bytes

f=lambda n,d:d<1or n/d*f(n+1,d-1)

Try it online!

R, 33 28 bytes

function(n,d)choose(n+d-1,d)

Try it online!

5 bytes saved by Dominic van Essen.

• Same approach but shorter: 28 bytes... Feb 21 '21 at 0:13

Husk, 5 bytes

→!¡∫ḣ

Try it online!

Same idea as my APL answer. Takes n and k, both 1 indexed, as command line args.

Charcoal, 18 13 bytes

≔…¹ＮθＩ÷Π⁺ＮθΠθ

Try it online! Link is to verbose version of code. Explanation: Now inspired by @KevinCruijssen's 05AB1E answer.

≔…¹Ｎθ

Input n and generate an exclusive range from 1 to n.

Ｉ÷Π⁺ＮθΠθ

Input d and vectorised add it to the range, then divide the product of that range by the product of the original range.

Java (JDK), 48 bytes

int f(int n,int d){return d<1?1:f(n+1,d-1)*n/d;}

Try it online!

Groovy, 27 bytes

f={n,d->d?f(n+1,d-1)*n/d:1}

Try it online!