Monday, April 30, 2012

Project Euler, Problem 15 solution

Problem 15

"Starting in the top left corner of a 2×2 grid, there are 6 routes (without backtracking) to the bottom right corner. How many routes are there through a 20×20 grid?"

This problem is about permutations and so called central binomial coefficient (the binomial theorem you must remember from the school). And do you remember the Pascal's triangle? If not, check it here. (If you still don't understand what I am talking about you can see the complete solution here).
All you need is to observe that for a NxN grid there are (2n)!/(n!)2 possible ways of getting from one corner to the other one and in our case it will be 40!/(20!)2. If you are still unable to calculate it you can use A000984.
But if you still want to get the answer by yourself, do not rush to crack factorials with your lovely brute force with 350 lines of C++ code, let's start from... little cheat.
We have some ways for cheat.
Of course we could use the J language to get the central binomial coefficient:
(! +:) 20x
or even more shorter:
20!40x
but it isn't real cheat. There is a better way: http://www.google.com/search?q=40+choose+20
Bingo? Btw. tell me truth, did you know that the Google calculator has the operator 'choose'? Brilliant, isn't? You just command "40 choose 20" and Google gives you the answer: please, master! Try the same way to ask Google for money ;)


Well, now let's start thinking.

Rudy Penteado from Brazil codes in Assembler language. He discovered that:
"This is what I find 2 months ago when I solved it:
Each movement in the horizontal is a zero.
Each movement in the vertical is a one.
1st binary# in this series:
0000000000000000000011111111111111111111
last:
1111111111111111111100000000000000000000
For the numbers in between, the amount of zeros should be the same as ones.
In other words, the ones and zeros have to be rearranged."

Easy, isn't? Try to code this in Assembler.
I won't. I did my solution with some magic too:

JavaScript (Spidermonkey)

var ans = 1;
for(var c = 40, d = 1; c > 20; --c, ++d) ans = (ans * c)/d;
print(ans);

// time: 0.02s memory: 4984 kB

Congratulations, the answer you gave to problem 15 is correct.
You are the 53180th person to have solved this problem.

No comments:

Post a Comment