private void SolveRecurse(Int32 index)
        {
            if (Equals(Root, Root.Right))
            {
                HandleSolution(_solutionsRows);             // No more columns, we found one solution.
            }
            else
            {
                DancingColumn nextCol = NextColumn();       // Select next column using some selection algorithm.
                CoverColumn(nextCol);                       // Exclude selected column from the matrix.
                DancingNode row = nextCol.Lower;            // Try for each row in selected column.
                while (Equals(row, nextCol) == false)
                {
                    _solutionsRows[index] = row;            // Add row to solutions array.
                    DancingNode col = row.Right;            // Exclude all columns covered by this row
                    while (Equals(col, row) == false)
                    {
                        CoverColumn(col.Header);
                        col = col.Right;
                    }
                    SolveRecurse(index + 1);                // And try to solve the reduced matrix.

                    col = row.Left;                         // Now, restore all columns covered by this row.
                    while (Equals(col, row) == false)
                    {
                        UncoverColumn(col.Header);
                        col = col.Left;
                    }
                    _solutionsRows[index] = null;           // And remove row from solution array.
                    row = row.Lower;
                }
                UncoverColumn(nextCol);                     // Return excluded column back to list.
            }
        }
        internal SudokuArena(Int32[,] puzzle, Int32 boxRows, Int32 boxCols)
            : base(puzzle.Length * 4)
        {
            Solutions = 0;
            Size      = puzzle.GetLength(0);
            Int32[]            positions = new Int32[4];
            List <DancingNode> known     = new List <DancingNode>();

            for (Int32 row = 0; row < Size; row++)
            {
                for (Int32 col = 0; col < Size; col++)
                {
                    Int32 boxRow = row / boxRows;
                    Int32 boxCol = col / boxCols;
                    for (Int32 digit = 0; digit < Size; digit++)
                    {
                        bool isGiven = (puzzle[row, col] == (digit + 1));
                        positions[0] = 1 + (row * Size + col);
                        positions[1] = 1 + puzzle.Length + (row * Size + digit);
                        positions[2] = 1 + 2 * puzzle.Length + (col * Size + digit);
                        positions[3] = 1 + 3 * puzzle.Length + ((boxRow * boxRows + boxCol) * Size + digit);
                        DancingNode newRow = AddRow(positions);
                        if (isGiven)
                        {
                            known.Add(newRow);
                        }
                    }
                }
            }
            RemoveKnown(known);
        }
 private static string Name(DancingNode node)
 {
     if (node == null)
     {
         return("NULL");
     }
     return(node.Name());
 }
示例#4
0
        internal void AddNode(DancingNode node)
        {
            DancingNode last = this.Upper;

            node.Upper = last;
            node.Lower = this;
            last.Lower = node;
            this.Upper = node;
            IncRows();
        }
        internal DancingNode AddRow(Int32[] positions)
        {
            DancingNode result = null;

            if (positions.Length > 0)
            {
                bool        found;
                DancingNode thisNode = null;
                DancingNode prevNode = null;
                Rows++;
                for (Int32 i = 0; i < positions.Length; i++)
                {
                    if (positions[i] > 0)
                    {
                        thisNode       = new DancingNode(Rows, positions[i]);
                        thisNode.Left  = prevNode;
                        thisNode.Right = null;
                        if (prevNode != null)
                        {
                            prevNode.Right = thisNode;
                        }
                        else
                        {
                            result = thisNode;
                        }
                        found = false;
                        for (Int32 j = 0; j < _headerColumns.Length; j++)
                        {
                            DancingColumn col = _headerColumns[j];
                            if (col.Col == positions[i])
                            {
                                thisNode.Header = col;
                                col.AddNode(thisNode);
                                found = true;
                            }
                        }
                        if (!found)
                        {
                            Debug.WriteLine("Can't find header for {0}.", positions[i]);
                        }
                        prevNode       = thisNode;
                        result.Left    = prevNode;
                        prevNode.Right = result;
                    }
                }
            }
            return(result);
        }
        internal void ShowState()
        {
            DancingColumn col = FirstColumn;

            while (Equals(col, Root) == false)
            {
                Debug.WriteLine("C : {0}", col.ToString());
                DancingNode row = col.Lower;
                while (Equals(row, col) == false)
                {
                    Debug.WriteLine("  R : {0}", row.ToString());
                    row = row.Lower;
                }
                col = (DancingColumn)col.Right;
            }
        }
 internal void RemoveKnown(List <DancingNode> solutions)
 {
     for (Int32 i = 0; i < solutions.Count; i++)
     {
         DancingNode row = solutions[i];
         _solutionsRows[Initial] = row;
         Initial++;
         CoverColumn(row.Header);
         DancingNode col = row.Right;
         while (Equals(col, row) == false)
         {
             CoverColumn(col.Header);
             col = col.Right;
         }
     }
 }
        private void UncoverColumn(DancingColumn column)
        {
            DancingNode row = column.Upper;

            while (Equals(row, column) == false)
            {
                DancingNode col = row.Left;
                while (Equals(col, row) == false)
                {
                    col.Upper.Lower = col;
                    col.Lower.Upper = col;
                    col.Header.IncRows();
                    col = col.Left;
                }
                row = row.Upper;
            }
            column.Left.Right = column;
            column.Right.Left = column;
        }