Beispiel #1
0
        private static byte[] Solve(Sudoku sudoku)
        {
            bool updated;
            bool solved;

            do
            {
                updated = false;
                solved  = true;

                for (int i = 0; i < sudoku.Answer.Length; i++)
                {
                    if (sudoku.Answer[i] != 0)
                    {
                        continue;
                    }
                    solved = false;

                    int c = sudoku.GetCandidateBit(i);
                    if (c == 0)
                    {
                        return(null);
                    }

                    int lowest = LowestOneBit(c);
                    if (c == lowest)
                    {
                        sudoku.Update(i, ToNum(lowest));
                        updated = true;
                    }
                }
            } while (updated);

            if (solved)
            {
                return(sudoku.Answer);
            }

            // 候補が少ない箇所を探す
            int count = int.MaxValue;
            int index = 0;

            for (int i = 0; i < sudoku.Answer.Length; i++)
            {
                if (sudoku.Answer[i] != 0)
                {
                    continue;
                }

                int c = BitCount(sudoku.GetCandidateBit(i));
                if (c < count)
                {
                    count = c;
                    index = i;
                }
            }

            // 複数ある候補のうちの一つを仮定して、再帰的に解析
            int candidate = sudoku.GetCandidateBit(index);

            for (int i = 0; i < 9; i++)
            {
                int bit = (candidate & (1 << i));
                if (bit == 0)
                {
                    continue;
                }

                Sudoku newSudoku = new Sudoku(sudoku);
                newSudoku.Update(index, (byte)(i + 1));

                byte[] answer = Solve(newSudoku);
                if (answer != null)
                {
                    return(answer);
                }
            }

            return(null);
        }