I agree that using randomness makes this difficult since you want an exact result and randomness doesn’t really lend itself towards that.
Yes, implementation can be tricky. I suggest starting with the most straight forward implementation you can think of and only optimize after you have confirmed that the algorithm is correct/promising and you need the increase in speed.
I will also remind you that you only care about the total count, not which numbers make up that count.
I think most other things, including finding out if your idea is on the right track or not, should be in your hands. If you have a Julia specific question I’m sure we can help you out. Best of luck!
When we think recursion we often think top to bottom like 5! = 54! etc. The other way to think of it is to build from bottom to top e.g. 0! = 1, 1 = 10!, 2 = 21! = 2, 3 = 32! = 3 * 2 = 6 etc.
For Haskell you can find a very elegant solution here: https://wiki.haskell.org/Euler_problems/161_to_170#Problem_164
Probably you have to invest some time for understanding the details as the program has no explanations. However it should be easy to transform this solution into a Julia program.
I think everyone gets essentially the same solution, after some reflection. But I noticed something weird with Julia. I wrote the following line inside my definition of the function P that solves the problem (I don’t give here the full code, because of the rules of the Euler project):
Yes, I agree it’s very sad that array slices allocate in Julia. I occasionally revert to Fortran for array-heavy codes for this exact reason. But let’s hope that some day this issue could be resolved. At the moment, you can use views or generators.
beta[i, j] = sum( view(alpha, j, 1:12-i-j) )
# OR
beta[i, j] = sum( alpha[j, k] for k in 1:12-i-j )
Memory allocations are less expensive, but don’t disappear (the line of code I’m talking about is indeed executed 18*55 = 990 times, and there are three obvious allocations in my code, e.g. when matrices alpha, beta are defined).