14
\$\begingroup\$

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.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – pxeger
    Commented Feb 18, 2021 at 9:44
  • 7
    \$\begingroup\$ Isn't it the same as nCr(n+d, d)? If so, I'm afraid it's a duplicate of existing nCr challenges. \$\endgroup\$
    – Bubbler
    Commented Feb 18, 2021 at 10:04
  • 4
    \$\begingroup\$ @Bubbler it's actually nCr(n+d, d-1) \$\endgroup\$
    – pxeger
    Commented Feb 18, 2021 at 10:14
  • \$\begingroup\$ If you index n from 0 and d from 1, then @Bubbler's formula is correct. \$\endgroup\$
    – xigoi
    Commented Feb 18, 2021 at 13:01
  • \$\begingroup\$ @pxeger xigoi is indeed correct: it's nCr(n+d-1, d). \$\endgroup\$ Commented Feb 18, 2021 at 13:55

21 Answers 21

7
\$\begingroup\$

JavaScript (ES6), 24 bytes

Expects (n)(d).

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

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ For posterity, since Arnauld's edits fell within the grace period: 36 34 \$\endgroup\$
    – pxeger
    Commented Feb 18, 2021 at 10:08
  • 2
    \$\begingroup\$ @pxeger The 34-byte version was really silly since k is not used anymore. :-p \$\endgroup\$
    – Arnauld
    Commented Feb 18, 2021 at 10:10
6
\$\begingroup\$

APL(Dyalog Unicode), 7 6 bytes SBCS

⊢!1-⍨+

Try it on APLgolf!, Old version(8 bytes)

-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
\$\endgroup\$
1
  • \$\begingroup\$ ⊢!1-⍨+ is 6 bytes \$\endgroup\$
    – rak1507
    Commented Feb 18, 2021 at 13:13
5
\$\begingroup\$

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

+’c   Main dyadic link
+     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

’çⱮSɗṛ’?   Main dyadic link
       ?   If
      ’    d-1 ≠ 0
    ɗ      then (
’            d-1
 ç           Apply this link
  Ɱ            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.

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

J, 6 bytes

[!<:@+

Try it online!

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

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.

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

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
\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can save 4 bytes by using named parameters tio.run/… \$\endgroup\$
    – Donat
    Commented Feb 20, 2021 at 18:29
  • \$\begingroup\$ 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 \$\endgroup\$
    – Kjetil S
    Commented Feb 21, 2021 at 20:59
2
\$\begingroup\$

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.

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

Haskell, 25 bytes

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!

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

Julia, 26 22 bytes

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

Try it online!

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

MathGolf, 8 bytes

r+k╒m╠ε*

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

Port of my 05AB1E answer.

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

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!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 51 bytes \$\endgroup\$
    – ovs
    Commented Feb 18, 2021 at 11:42
  • \$\begingroup\$ @ovs You took my brains to another dimension - thanks! :D \$\endgroup\$
    – Noodle9
    Commented Feb 18, 2021 at 12:05
1
\$\begingroup\$

05AB1E, 9 7 4 bytes

+<Ic

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

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

Try it online or verify some more test cases.

Previous 7 bytes answers:

L©<+®/P

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

Try it online or verify some more test cases.

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

LIGηO}θ

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

Try it online or verify some more test cases.

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

Haskell, 44 39 bytes

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

Try it online!

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

Rust, 63 58 bytes

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

Try it online! (with calling code)

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

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~#).

\$\endgroup\$
3
  • \$\begingroup\$ Nice! Mathematica has bultins for practically every purpose, so nice job not using them! \$\endgroup\$
    – emanresu A
    Commented Feb 19, 2021 at 8:08
  • 1
    \$\begingroup\$ 35 bytes \$\endgroup\$
    – att
    Commented Feb 20, 2021 at 3:33
  • \$\begingroup\$ Ah yes, I forget that Table can do this, thanks :) \$\endgroup\$ Commented Feb 20, 2021 at 7:54
1
\$\begingroup\$

Python 3, 33 bytes

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

Try it online!

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

R, 33 28 bytes

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

Try it online!

5 bytes saved by Dominic van Essen.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Same approach but shorter: 28 bytes... \$\endgroup\$ Commented Feb 21, 2021 at 0:13
0
\$\begingroup\$

Husk, 5 bytes

→!¡∫ḣ

Try it online!

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

\$\endgroup\$
0
\$\begingroup\$

Java (JDK), 48 bytes

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Groovy, 27 bytes

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Charcoal, 18 13 bytes

≔…¹NθI÷Π⁺NθΠθ

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

≔…¹Nθ

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

I÷Π⁺NθΠθ

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

\$\endgroup\$

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