Esempio n. 1
0
        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++;
            }
        }