static void Main(string[] args) { SudokuDebug.Run(args); }
/* A total of 17 static methods in the class: * CopyList * CopySudokuBoard * GetInputSudokuBoard * NumberIsAloneCandidate * RemoveNumberIfItExists * ReturnNumberOfOccurenciesOfNumber * ReturnTwoDimensionalDataStructure * ReturnThreeDimensionalDataStructure * ReturnSquareCellToRowColumnMapper * ReturnSudokuBoardsAsString * SimulateOneNumber * InitCandidates (Dependent on ReturnNumberOfOccurenciesOfNumber) * TryFindNumberToSetInCellWithCertainty (Dependent on NumberIsAloneCandidate) * UpdateCandidates (Dependent on RemoveNumberIfItExists) * ValidateSudokuBoard (Dependent on ReturnNumberOfOccurenciesOfNumber) * PrintSudokuBoard (Dependent on ReturnSudokuBoardsAsString) * Run (Dependent on GetInputSudokuBoard, ValidateSudokuBoard, ReturnTwoDimensionalDataStructure, SimulateOneNumber, ReturnThreeDimensionalDataStructure, ReturnSquareCellToRowColumnMapper, InitCandidates, TryFindNumberToSetInCellWithCertainty, CopyList, CopySudokuBoard, UpdateCandidates, PrintSudokuBoard) */ public static void Run(string[] args) { int row = 0, column = 0, number, i; int[][] certaintySudokuBoard = null; int[][] workingSudokuBoard = ReturnTwoDimensionalDataStructure(9, 9); int[][] bestSoFarSudokuBoard = ReturnTwoDimensionalDataStructure(9, 9); int[][][] candidates, squareCellToRowColumnMapper; int maxNumberOfAttemptsToSolveSudoku = 25, numberOfAttemptsToSolveSudoku = 0; int numberOfCellsSetInInputSudokuBoard, numberOfCellsSetInBestSoFar = 0, numberOfCandidates; bool sudokuSolved = false, numbersAddedWithCertaintyAndThenNoCandidates = false; Random random = new Random((int)(DateTime.Now.Ticks % 64765L)); string msg; ArrayList cellsRemainToSet = new ArrayList(); ArrayList cellsRemainToSetAfterAddedNumbersWithCertainty = null; SudokuDebug sudokuDebug = new SudokuDebug(); string category = "", fileNameFullPath; int minNumberOfCandidates; string cellsThatHaveMinNumberOfCandidates; msg = GetInputSudokuBoard(args, workingSudokuBoard, cellsRemainToSet); if (msg != null) { Console.Write(msg); return; } squareCellToRowColumnMapper = ReturnSquareCellToRowColumnMapper(); msg = ValidateSudokuBoard(workingSudokuBoard, squareCellToRowColumnMapper); if (msg != null) { Console.Write(msg); return; } if (cellsRemainToSet.Count == 0) { Console.Write("A complete sudoku was given as input. There is nothing to solve."); return; } candidates = ReturnThreeDimensionalDataStructure(9, 9, 10); numberOfCandidates = InitCandidates(workingSudokuBoard, squareCellToRowColumnMapper, candidates); if (numberOfCandidates == 0) { Console.WriteLine("It is not possible to add any number to the sudoku."); return; } numberOfCellsSetInInputSudokuBoard = 81 - cellsRemainToSet.Count; while (numberOfAttemptsToSolveSudoku < maxNumberOfAttemptsToSolveSudoku && !sudokuSolved && !numbersAddedWithCertaintyAndThenNoCandidates) { if (numberOfAttemptsToSolveSudoku > 0) { CopySudokuBoard(certaintySudokuBoard, workingSudokuBoard); CopyList(cellsRemainToSetAfterAddedNumbersWithCertainty, cellsRemainToSet); numberOfCandidates = InitCandidates(workingSudokuBoard, squareCellToRowColumnMapper, candidates); } while (numberOfCandidates > 0) { number = 0; i = 0; while (i < cellsRemainToSet.Count && number == 0) { row = ((int[])cellsRemainToSet[i])[0]; column = ((int[])cellsRemainToSet[i])[1]; number = TryFindNumberToSetInCellWithCertainty(row, column, candidates, squareCellToRowColumnMapper, out category); i = (number == 0) ? i + 1 : i; } if (number == 0) { SimulateOneNumber(candidates, random, cellsRemainToSet, out i, out number, out minNumberOfCandidates, out cellsThatHaveMinNumberOfCandidates); row = ((int[])cellsRemainToSet[i])[0]; column = ((int[])cellsRemainToSet[i])[1]; if (certaintySudokuBoard == null) { certaintySudokuBoard = ReturnTwoDimensionalDataStructure(9, 9); cellsRemainToSetAfterAddedNumbersWithCertainty = new ArrayList(); CopySudokuBoard(workingSudokuBoard, certaintySudokuBoard); CopyList(cellsRemainToSet, cellsRemainToSetAfterAddedNumbersWithCertainty); } category = "Simulated"; } else { minNumberOfCandidates = -1; cellsThatHaveMinNumberOfCandidates = ""; } fileNameFullPath = sudokuDebug.Log(1 + numberOfAttemptsToSolveSudoku, row, column, number, category, workingSudokuBoard, candidates, numberOfCandidates, cellsRemainToSet, minNumberOfCandidates, cellsThatHaveMinNumberOfCandidates); workingSudokuBoard[row - 1][column - 1] = number; cellsRemainToSet.RemoveAt(i); numberOfCandidates -= UpdateCandidates(candidates, squareCellToRowColumnMapper, row, column, number); sudokuDebug.Log(fileNameFullPath, workingSudokuBoard, candidates, numberOfCandidates, cellsRemainToSet, squareCellToRowColumnMapper); } if (numberOfCellsSetInBestSoFar < (81 - cellsRemainToSet.Count)) { numberOfCellsSetInBestSoFar = 81 - cellsRemainToSet.Count; CopySudokuBoard(workingSudokuBoard, bestSoFarSudokuBoard); } if (cellsRemainToSet.Count == 0) { sudokuSolved = true; } else if (certaintySudokuBoard == null) { numbersAddedWithCertaintyAndThenNoCandidates = true; } else { numberOfAttemptsToSolveSudoku++; } } if (numberOfCellsSetInBestSoFar == 81) { msg = string.Format("The sudoku was solved. {0} numbers added to the original {1}", 81 - numberOfCellsSetInInputSudokuBoard, numberOfCellsSetInInputSudokuBoard); } else { msg = string.Format("The sudoku was partially solved. {0} numbers added to the original {1}. Unable to set {2} number(s).", numberOfCellsSetInBestSoFar - numberOfCellsSetInInputSudokuBoard, numberOfCellsSetInInputSudokuBoard, 81 - numberOfCellsSetInBestSoFar); } PrintSudokuBoard(numberOfCellsSetInBestSoFar == 81 ? true : false, args, msg, bestSoFarSudokuBoard); Console.Write(msg); }