
Super Lloyd wrote: level N has N(N+1)/2 balls
Points for realizing this. I too realized this, but couldn't remember the exact function.





My shot at the answer  quick and not optimized, I'm sure
class Program
{
const int RANGE = 1000;
static void Main( string[] args )
{
int sum, p1, p2;
for( int a = 0; a < RANGE; a++ )
{
p1 = ( a * ( a + 1 ) * ( a + 2 ) ) / 6;
for( int b = a + 1; b < RANGE; b++ )
{
p2 = ( b * ( b + 1 ) * ( b + 2 ) ) / 6;
for( int i = b + 1; i < RANGE; i++ )
{
sum = ( i * ( i + 1 ) * ( i + 2 ) ) / 6;
if( sum == p1 + p2 )
{
Console.WriteLine( sum.ToString() + "=" + p1.ToString() + "+" + p2.ToString() + "\n" );
}
}
}
}
Console.ReadKey();
}
}
SPOILER ALERT!!
The answer I got is:
680 = 120 + 560
EDIT: I am aware I could have just stopped looking after the first hit  but I was also curious if there would be a lot of results





Points awarded for: correctness, elegance, quickness, and mathematical insight. It seems you found an equation for the number of elements in a pyramid for the Nth pyramid. Nice! Since you already have a better program than mine, I might as well share mine now instead of waiting until tomorrow:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
for (var i = 1; i <= 30; i++)
{
txtOut.AppendText(Environment.NewLine + CalculateNumBalls(i).ToString());
}
}
public int CalculateNumBalls(int index)
{
if (index <= 1)
{
return index;
}
else
{
return CalculateNumBalls(index  1) + CalculateLayer(index);
}
}
public int CalculateLayer(int index)
{
int total = 0;
for (var i = 1; i <= index; i++)
{
total += i;
}
return total;
}
}
That just displays the number of balls in the Nth pyramid for the first thirty pyramids. I just used a calculator to see what the difference was between each number. I saved time because I didn't have to calculate all the way down (given largePyramid  mediumPyramid = smallPyramid, I could just stop when smallPyramid was larger than mediumPyramid).
Out of curiosity, did you know that formula already, or did you figure it out?





To tell you the truth I had to Google 'tetrahedral' to begin with ( my knowledge of English is limited I'm afraid ), which led me to: here[^] and later (through the See Also section) to
here[^]
Things were kind of obvious from there Thank you wikipedia





Points awarded for sharing your research techniques, for pointing me to this GIF, and for figuring out a solution so fast without even knowing what a "tetrahedral" is.





The number of balls for each level of the pyramid increases like: 1, 3, 6, 10, 15, 21, 28.
This means that the number of balls for each larger pyramid is as follows: 4, 10, 20, 35, 56, 84.
So we are looking for a pyramid size that can be created with the sizes of the two pyramids that go before it. 84 is the first number for which this is possible, being combined from the pyramids with 35 and 56 balls.
0100000101101110011001000111001011101001





From the OP:
(assuming he uses every cannonball in both pyramids)





Not only is this answer not the smallest possible value, but if you start with tetrahedra of order 35 and 56, you won't have anywhere near enough cannon balls to build a tetrahedon of order 84.






How does that relate to the cannonball problem?





AspDotNetDev wrote: How does that relate to the cannonball problem?
Exercise for the reader
(Can you not see the symmetry?)





leppie wrote: Can you not see the symmetry?
They both involve triangles. Other than that, nope.





The way I see it, each stack must have a number of cannonballs from the set {1, 4, 10, 20, 35...}
Now we are looking for a minimum A and B, both out of this set, so that the sum of both is also in the set. From your example we know it works for two stacks of 10 cannonballs, so the sum cannot be greater than 20. Therefore A and B must both be in {1, 4, 10}
Now you can simply try all combinations:
A  B  Sum  Sum <= 20  Sum in set
====================================
1  1  2  Y  N
1  4  5  Y  N
1 10  11  Y  N
4  1  5  Y  N
4  4  8  Y  N
4 10  14  Y  N
10 1  11  Y  N
10 4  14  Y  N
1010  20  Y  Y
So here we have it. Your example with two stacks of 10 cannonballs already is the minimum.
Edit: Added pre tags to make the table readable
I'm invincible, I can't be vinced
modified 24Jan12 3:40am.





Nope, there was a stipulation that A and B are different. Otherwise, you are one the right track.





Hi AspDotNetDev,
In this comment to your good self(ves?)[^], I think you raised an issue appropriate for "Site Suggs and Buggs:" and I have expressed my views there:[^].
And, to this starving worm on a wilted cabbage leaf, the issue raised by that post is an even more compelling puzzle than the stacking of cannonballs, although I am not denigrating the value of considering the stacking of cannon balls !
best, Bill
"Science is facts; just as houses are made of stones: so, is science made of facts. But, a pile of stones is not a house, and a collection of facts is not, necessarily, science." Henri Poincare





I did this using an old technique: pencil and paper. It is more complicated to explain than it was to do. Basically, I wrote 3 columns of numbers:
Col 1: 1, 2, 3, 4, etc [represents the no of levels in the pyramid)
Col 2: 1, (corresponding no in col 1 + prev number in col 2), ... [represents the no of new balls in the new level of the pyramid]
Col 3: 1, (corresponding no in col 2 + prev number in col 3), ... [represents the total no of balls in the pyramid]
and then looked for a number in col 2 that was the same as a number in col 3 which is a pyramid's worth of balls that is also a level's worth of balls
[Actually, I didn't bother with col 1  I could work that one out without writing it down, but it is easier to explain with it there]
My solution is ...
The first one found was 120, so the solution is 120 + 560 (no in col 3 before the 120 in col 2) = 680 (no in col 3 next to 120 in col 2).
(select the text in the gap above, e.g. by dragging the mouse, to read it)
Of course, this discounts the possibility that a pyramid might split across multiple levels in a combined pyramid.
Just in case I had made a simple arithmetic error, I checked in MSExcel:
Cell A1 = 1, B1 = 1, C1 = 1
Cell A2 = =A1+1, B2 = =A2+B1, C2 = =B2+C1
Cells A3 through C17 = Copy and paste A2 through C2
[I've had to edit this entry twice  suffering from lysdexia (!) today].





Good call on confirming you didn't make an error. I started out on paper and indeed made an error, which I happened to spot when I made the C# program.





jsc42 wrote: lysdexia
I thought I was the only one who used that word. Actually, I saw it on some nature show when I was younger and have been using it ever since.





AspDotNetDev wrote: I saw it on some nature show when I was younger
It would be more amazing if you'd been using it after seeing it when you were older. It is implicit that you were younger than you are now when you saw it.
I've been using the word for years  I cannot recall if I saw it anywhere or if I made it up as a self describing word.
There is a word for self describing words but I cannot recall what it is (it isn't onomatopoeia  that's words that sound like what they represent) and there is an antonym for words that describe their opposites (e.g. fat is a very thin word).
Some CPian took this to another level (I forget who) with a self describing acronym in their signature block: "I have CDO  it's like OCD but arranged alphabetically"
Thanks to whoever can tell me what the word for self describing words in and what its antonym is.
Thanks too to AspDotNetDev for the challenge  the large no of responses shows that you hit a hot spot.





jsc42 wrote: It would be more amazing if you'd been using it after seeing it when you were older. It is implicit that you were younger than you are now when you saw it.
Do you tell people that you are 30 years and 200 days old, or do you tell them you are 30 years old? I age in large discrete units. If I were the same age I am now, I wouldn't be younger.





1) looked up the tetrahedral numbers in Wikipedia and found this list: 1, 4, 10, 20, 35, 56, 84, 120, 165, 220, 286, 364, 455, 560, 680, 816, 969... (10 seconds of work)
2) opened an Excel sheet and created the table of sums
2 5 11 21 36 57...
5 8 14 24 39 60...
11 14 20 30 45 66...
21 24 30 40 55 76...
36 39 45 55 70 91...
...
(just needed to recall the appropriate syntax to form the cell expression; 1 minute of work)
3) sorted all sums in increasing order
2, 5, 5, 8, 11, 11, 14, 14, 20, 21, 21, 24, 24, 30, 30, 36, 36, 39, 39, 40, 45, 45, 55, 55, 57, 57, 60, 60, 66, 66, 70, 76, 76, 85, 85, 88, 88, 91, 91, ...
(moved to Word to flatten the table structure; 1 minute of work)
4) spotted by eye in the list the first tetrahedral number larger than 20: 680, the sum of 120 and 560. (Lucky the Wikipedia list was long enough )
(2 extra minutes)
5) explained the answer in CodeProject (half an hour)
modified 25Jan12 9:16am.





Points awarded for getting as close as possible to cheating without fully qualifying as cheating.






Well, using a bit of python:
def pyr(l):
if l==0:
return 0
elif l==1:
return 1
else:
return pyr(l1)+l*(l+1)/2
#then we bruteforce
a=[pyr(i) for i in range(100)][1:]
b=[(i,j,k) for i in a
for j in a
for k in a
if (i!=j and i+j==k)]
if len(b)>0:
print b[0]
Running the above yields the result as
(120, 560, 680)
as others have already pointed out...
(Edit: changed the type from general to Answer)
Φευ! Εδόμεθα υπό ρηννοσχήμων λύκων!
(Alas! We're devoured by lambguised wolves!)





A Python script can do.
Grow a list of tetrahedral numers; for every new number, try and find a number in the list such that when subtracted from the new number, it gives another number in the list. (This way you make sure that for every new number the two terms of the decomposition are already in the list.)
# Start with an empty list
List= {}
n= 1
while n > 0:
# Try the next tetrahedral number
r= n * (n + 1) * (n + 2) / 6
# Try every number in the list
for p in List:
# Lookup the difference between the new number and the current one
q= r  p
if p != q and q in List:
print p, '+', q, '=', r
# Flag as found
n= 1
break
# Not found, extend the list
List[r]= None
n+= 1
For efficiency of the search, the list is implemented as a dictionnary.
Yields:
560 + 120 = 680




