Just stumbled upon this question - here is a C # variation that allows you to explore different combinations:
static class SlotIterator { public static IEnumerable<string> Discover(this int[] set, int maxScore) { var st = new Stack<Slot>(); var combinations = 0; set = set.OrderBy(c => c).ToArray(); st.Push(new Slot(0, 0, set.Length)); while (st.Count > 0) { var m = st.Pop(); for (var i = m.Index; i < set.Length; i++) { if (m.Counter + set[i] < maxScore) { st.Push(m.Clone(m.Counter + set[i], i)); } else if (m.Counter + set[i] == maxScore) { m.SetSlot(i); yield return m.Slots.PrintSlots(set, ++combinations, maxScore); } } } } public static string PrintSlots(this int[] slots, int[] set, int numVariation, int maxScore) { var sb = new StringBuilder(); var accumulate = 0; for (var j = 0; j < slots.Length; j++) { if (slots[j] <= 0) { continue; } var plus = "+"; for (var k = 0; k < slots[j]; k++) { accumulate += set[j]; if (accumulate == maxScore) plus = ""; sb.AppendFormat("{0}{1}", set[j], plus); } } sb.AppendFormat("={0} - Variation nr. {1}", accumulate, numVariation); return sb.ToString(); } } public class Slot { public Slot(int counter, int index, int countSlots) { this.Slots = new int[countSlots]; this.Counter = counter; this.Index = index; } public void SetSlot(int index) { this.Slots[index]++; } public Slot Clone(int newval, int index) { var s = new Slot(newval, index, this.Slots.Length); this.Slots.CopyTo(s.Slots, 0); s.SetSlot(index); return s; } public int[] Slots { get; private set; } public int Counter { get; set; } public int Index { get; set; } }
Example:
static void Main(string[] args) { using (var sw = new StreamWriter(@"c:\test\comb50.txt")) { foreach (var s in new[] { 2, 3, 4, 5, 6, 7, 8 }.Discover(50)) { sw.WriteLine(s); } } }
Sets 3095 combinations.
source share