Exemplo n.º 1
0
        public MainWindow()
        {
            InitializeComponent();

            PairComparer <int> pc = new PairComparer <int>();

            invalidChoices = new Dictionary <Pair <int>, List <int> >(pc);
            filledSquares  = new Dictionary <Pair <int>, int>(pc);

            gr = new SudokuGrid();

            grid.Children.Add(gr);
        }
Exemplo n.º 2
0
        static void Main()
        {
            SudokuGrid grid = new SudokuGrid();

            while (grid.UnknownSquares > 0)
            {
                for (int i = 0; i < grid.inputArray.Length; i++)
                {
                    if (grid.inputArray[i] == 0)
                    {
                        grid.inputArray[i] = new Element(grid, i).Decide();
                    }
                }
            }
            PrintOutput(grid.inputArray);
        }
Exemplo n.º 3
0
        public DancingLinks(SudokuGrid s)
        {
            rowLookUp = new Dictionary <Triple <int>, SudokuRowHeader>();


            if (s.Validate())
            {
                columns = new List <DancingLinksColumnHeader>();
                rows    = new List <SudokuRowHeader>();


                //Initialise blank Sudoku Grid.


                for (int i = 1; i <= 9; i++)
                {
                    for (int j = 1; j <= 9; j++)
                    {
                        columns.Add(new DancingLinksColumnHeader(new Tuple <int, int>(i, j), DancingLinksColumnHeader.ColumnType.Cell));
                        columns.Add(new DancingLinksColumnHeader(new Tuple <int, int>(i, j), DancingLinksColumnHeader.ColumnType.Row));
                        columns.Add(new DancingLinksColumnHeader(new Tuple <int, int>(i, j), DancingLinksColumnHeader.ColumnType.Square));
                        columns.Add(new DancingLinksColumnHeader(new Tuple <int, int>(i, j), DancingLinksColumnHeader.ColumnType.Column));


                        for (int k = 1; k <= 9; k++)
                        {
                            SudokuRowHeader r = new SudokuRowHeader(new Triple <int>(i, j, k));
                            rows.Add(r);
                            rowLookUp.Add(new Triple <int>(i, j, k), r);
                        }
                    }
                }

                //Convention: for cell numbers, x is the row and y is the column. This is reversed for square numbering. This is an artefact of how I am visualising the objects.

                //Column Linking
                foreach (DancingLinksColumnHeader column in columns)
                {
                    column.columnMemberCount = 9;

                    if (column.type == DancingLinksColumnHeader.ColumnType.Cell)
                    {
                        int content;
                        if (int.TryParse(s.boxes[column.constraintNum.Item1 - 1, column.constraintNum.Item2 - 1].Text, out content))
                        {
                            column.columnMemberCount = 1;
                            column.firstEntry        = new DancingLinksNode(column, column.constraintNum.Item1, column.constraintNum.Item2, content);

                            column.firstEntry.up   = column.firstEntry;
                            column.firstEntry.down = column.firstEntry;

                            if (rowLookUp.ContainsKey(new Triple <int>(column.constraintNum.Item1, column.constraintNum.Item2, content)))
                            {
                                rowLookUp[new Triple <int>(column.constraintNum.Item1, column.constraintNum.Item2, content)].firstNode.left.right = column.firstEntry;
                                rowLookUp[new Triple <int>(column.constraintNum.Item1, column.constraintNum.Item2, content)].firstNode.left       = column.firstEntry;
                            }
                            else
                            {
                                SudokuRowHeader r = new SudokuRowHeader(new Triple <int>(column.constraintNum.Item1, column.constraintNum.Item2, content));
                                rows.Add(r);
                                rowLookUp.Add(new Triple <int>(column.constraintNum.Item1, column.constraintNum.Item2, content), r);

                                r.firstNode = column.firstEntry;
                            }
                        }
                        else
                        {
                            column.firstEntry = new DancingLinksNode(column, column.constraintNum.Item1, column.constraintNum.Item2, 1);

                            DancingLinksNode curNode = column.firstEntry;

                            if (rowLookUp.ContainsKey(new Triple <int>(column.constraintNum.Item1, column.constraintNum.Item2, 1)))
                            {
                                rowLookUp[new Triple <int>(column.constraintNum.Item1, column.constraintNum.Item2, 1)].firstNode.left.right = curNode;
                                rowLookUp[new Triple <int>(column.constraintNum.Item1, column.constraintNum.Item2, 1)].firstNode.left       = curNode;
                            }
                            else
                            {
                                SudokuRowHeader r = new SudokuRowHeader(new Triple <int>(column.constraintNum.Item1, column.constraintNum.Item2, 1));
                                rows.Add(r);
                                rowLookUp.Add(new Triple <int>(column.constraintNum.Item1, column.constraintNum.Item2, 1), r);

                                r.firstNode = curNode;
                            }


                            for (int i = 2; i <= 9; i++)
                            {
                                curNode.down    = new DancingLinksNode(column, column.constraintNum.Item1, column.constraintNum.Item2, i);
                                curNode.down.up = curNode;
                                curNode         = curNode.down;

                                if (i == 9)
                                {
                                    column.firstEntry.up = curNode;
                                    curNode.down         = column.firstEntry;
                                }

                                if (rowLookUp.ContainsKey(new Triple <int>(column.constraintNum.Item1, column.constraintNum.Item2, i)))
                                {
                                    rowLookUp[new Triple <int>(column.constraintNum.Item1, column.constraintNum.Item2, i)].firstNode.left.right = curNode;
                                    rowLookUp[new Triple <int>(column.constraintNum.Item1, column.constraintNum.Item2, i)].firstNode.left       = curNode;
                                }
                                else
                                {
                                    SudokuRowHeader r = new SudokuRowHeader(new Triple <int>(column.constraintNum.Item1, column.constraintNum.Item2, i));
                                    rows.Add(r);
                                    rowLookUp.Add(new Triple <int>(column.constraintNum.Item1, column.constraintNum.Item2, i), r);

                                    r.firstNode = curNode;
                                }
                            }
                        }
                    }

                    if (column.type == DancingLinksColumnHeader.ColumnType.Column)
                    {
                        int  content;
                        int  rowNum     = 0;
                        bool isInColumn = false;

                        for (int i = 1; i <= 9 && !isInColumn; i++)
                        {
                            if (int.TryParse(s.boxes[i - 1, column.constraintNum.Item1 - 1].Text, out content))
                            {
                                if (content == column.constraintNum.Item2)
                                {
                                    isInColumn = true;
                                }
                                rowNum = i;
                            }
                        }

                        if (isInColumn)
                        {
                            column.columnMemberCount = 1;

                            column.firstEntry      = new DancingLinksNode(column, rowNum, column.constraintNum.Item1, column.constraintNum.Item2);
                            column.firstEntry.up   = column.firstEntry;
                            column.firstEntry.down = column.firstEntry;
                        }
                        else
                        {
                            column.firstEntry = new DancingLinksNode(column, 1, column.constraintNum.Item1, column.constraintNum.Item2);

                            DancingLinksNode curNode = column.firstEntry;


                            for (int i = 2; i <= 9; i++)
                            {
                                curNode.down    = new DancingLinksNode(column, i, column.constraintNum.Item1, column.constraintNum.Item2);
                                curNode.down.up = curNode;
                                curNode         = curNode.down;

                                if (i == 9)
                                {
                                    column.firstEntry.up = curNode;
                                    curNode.down         = column.firstEntry;
                                }
                            }
                        }
                    }

                    if (column.type == DancingLinksColumnHeader.ColumnType.Row)
                    {
                        int  content;
                        int  colNum     = 0;
                        bool isInColumn = false;

                        for (int i = 1; i <= 9 && !isInColumn; i++)
                        {
                            if (int.TryParse(s.boxes[column.constraintNum.Item1 - 1, i - 1].Text, out content))
                            {
                                if (content == column.constraintNum.Item2)
                                {
                                    isInColumn = true;
                                }
                                colNum = i;
                            }
                        }

                        if (isInColumn)
                        {
                            column.columnMemberCount = 1;

                            column.firstEntry      = new DancingLinksNode(column, column.constraintNum.Item1, colNum, column.constraintNum.Item2);
                            column.firstEntry.up   = column.firstEntry;
                            column.firstEntry.down = column.firstEntry;
                        }
                        else
                        {
                            column.firstEntry = new DancingLinksNode(column, column.constraintNum.Item1, 1, column.constraintNum.Item2);

                            DancingLinksNode curNode = column.firstEntry;


                            for (int i = 2; i <= 9; i++)
                            {
                                curNode.down    = new DancingLinksNode(column, column.constraintNum.Item1, i, column.constraintNum.Item2);
                                curNode.down.up = curNode;
                                curNode         = curNode.down;

                                if (i == 9)
                                {
                                    column.firstEntry.up = curNode;
                                    curNode.down         = column.firstEntry;
                                }
                            }
                        }
                    }

                    if (column.type == DancingLinksColumnHeader.ColumnType.Square)
                    {
                        int squareX = column.constraintNum.Item1 % 3 - 1;
                        if (squareX < 0)
                        {
                            squareX += 3;
                        }
                        int squareY = (column.constraintNum.Item1 - (squareX + 1)) / 3;

                        int rowNum = 0;
                        int colNum = 0;

                        bool isInSquare = false;

                        for (int i = 1; i <= 3; i++)
                        {
                            for (int j = 1; j <= 3; j++)
                            {
                                int content;

                                if (int.TryParse(s.boxes[squareY * 3 + i - 1, squareX * 3 + j - 1].Text, out content))
                                {
                                    if (content == column.constraintNum.Item2)
                                    {
                                        isInSquare = true;

                                        rowNum = squareY * 3 + i;
                                        colNum = squareX * 3 + j;
                                    }
                                }
                            }
                        }

                        if (isInSquare)
                        {
                            column.columnMemberCount = 1;

                            column.firstEntry = new DancingLinksNode(column, rowNum, colNum, column.constraintNum.Item2);


                            column.firstEntry.up   = column.firstEntry;
                            column.firstEntry.down = column.firstEntry;
                        }
                        else
                        {
                            column.firstEntry = new DancingLinksNode(column, squareY * 3 + 1, squareX * 3 + 1, column.constraintNum.Item2);
                            DancingLinksNode curNode = column.firstEntry;


                            for (int i = 1; i <= 3; i++)
                            {
                                for (int j = 1; j <= 3; j++)
                                {
                                    if (i != 1 || j != 1)
                                    {
                                        curNode.down    = new DancingLinksNode(column, squareY * 3 + i, squareX * 3 + j, column.constraintNum.Item2);
                                        curNode.down.up = curNode;
                                        curNode         = curNode.down;
                                    }

                                    if (i == 3 && j == 3)
                                    {
                                        column.firstEntry.up = curNode;
                                        curNode.down         = column.firstEntry;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }