void GenerateAllBoards(Template template, int colorCount, Action <Tuple <string, int> > progress = null) { var boards = new HashSet <Board>(); var vertices = Enumerable.Range(0, template.Sizes.Count).ToList(); var potSet = Enumerable.Range(0, colorCount).ToList(); var pot = potSet.ToInt64(); var fix = vertices.OrderBy(v => Math.Abs(template.Sizes[v] - colorCount / 2)).First(); var lastP = -1; var current = 0; var total = vertices.Aggregate(1L, (x, v) => { if (v == fix) { return(x); } return(x * ListUtility.BinomialCoefficient(potSet.Count, template.Sizes[v])); }); foreach (var assignmentSets in vertices.Select(v => { if (v == fix) { return(potSet.Take(template.Sizes[v]).ToList().EnList()); } return(ListUtility.EnumerateSublists(potSet, template.Sizes[v])); }).CartesianProduct()) { var sets = assignmentSets.ToList(); var totalColors = sets.SelectMany(set => set).Distinct().Count(); if (totalColors < colorCount) { continue; } var stacks = sets.Select(list => list.ToInt64()).ToList(); if (SuperabundantOnly && !Knowledge.GraphKnowledge.Graph.DegreeCondition(stacks, pot)) { continue; } var board = new Board(stacks, pot); var count = boards.Count; boards.Add(board); if (boards.Count > count) { BoardLookup[NextBoardID] = board; BoardIDLookup[board] = NextBoardID; NextBoardID++; } if (progress != null) { var p = (int)(100 * current / total); if (p > lastP) { progress(new Tuple <string, int>("Finding all positions...", p)); lastP = p; } } current++; } }