Here is how Project Euler Problem #76 sounds like:
“How many different ways can one hundred be written as a sum of at least two positive integers?”
I’ve struggled to get it right for a couple of days, tried to solve in different ways and got mostly the same results for small numbers (those that are easy to check). I ended up with an algorithm that lists all partitions for a given number in alphabetical order, descending (starting from “N-1 + 1”). Written in VB.NET:
Dim ub As Integer = 6
Dim wayCount As Integer = 0
For n = ub - 1 To 1 Step -1
'init value array (first combination)
Dim s As New List(Of Integer)
For m = 1 To ub \ n : s.Add(n) : Next
Dim b As Integer = ub Mod n
If b <> 0 Then s.Add(b)
'from where to start decrementing
Dim k As Integer = s.Count - 1
While k > 0 And s(k) = 1 : k -= 1 : End While
Do
wayCount += 1 : Console.WriteLine(String.Join(" + ", s) & " = " & s.Sum)
If s(k) = 1 Then k -= 1
If k = -1 Then Exit Do
s(k) -= 1
s.Add(1)
Loop While k >= 1
Next
Console.WriteLine("count=" & wayCount)
The code works for numbers 1-6 inclusive and starts failing for N=7, with 1 combination missed. For N=8 it misses 2 (19 instead of 21). For N=100 the answer is 4576, which is several orders of magnitude less than required. Clearly, I am missing some very important detail.
If you don’t have time or means to compile and run the above code, here is the output (N=7):
6 + 1 = 7
5 + 2 = 7
5 + 1 + 1 = 7
4 + 3 = 7
4 + 2 + 1 = 7
4 + 1 + 1 + 1 = 7
3 + 3 + 1 = 7
3 + 2 + 1 + 1 = 7
3 + 1 + 1 + 1 + 1 = 7
2 + 2 + 2 + 1 = 7
2 + 2 + 1 + 1 + 1 = 7
2 + 1 + 1 + 1 + 1 + 1 = 7
1 + 1 + 1 + 1 + 1 + 1 + 1 = 7
count=13
I’ve studied these links:
(ProjectEuler) Sum Combinations – provides a mathematical solution, which does not list all combinations
Generating the partitions of a number – is in python, which I cannot read/run/understand.
Any help would be much appreciated, thanks in advance!
As promised, here is some code that does partitioning of N (stored in ub) using natural numbers up to N, but not including it. With slight modification, it should be able to partition by any function, including that with floating point output.
Basic idea is that for every value used in partitioning we are using coefficient bucket, which is a multiplier of that value. On every step we either charge the value to maximum available, move left or right, decrement current multiplier and test if we get to the sum. Once sum was successfully partitioned, wayCount is incremented and result is printed to the screen.
This might be a somewhat dirty implementation, but it works in a reasonable time even for the scope of the problem in question (under 5 minutes on my machine), generating several millions of partitions per second. Healthy criticism is always welcome!