add solver
This commit is contained in:
		
							parent
							
								
									dccf9b3616
								
							
						
					
					
						commit
						f6c80ebcfa
					
				| @ -94,6 +94,15 @@ function showBoard(board) | |||||||
|     end |     end | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
|  | function checkBoardsEqual(b1, b2) | ||||||
|  |     for i = 1, 9 do | ||||||
|  |         for j = 1, 9 do | ||||||
|  |             if b1[i][j] ~= b2[i][j] then return false end | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |     return true | ||||||
|  | end | ||||||
|  | 
 | ||||||
| function iterZones(board) | function iterZones(board) | ||||||
|     local row = 0 |     local row = 0 | ||||||
|     local column = 0 |     local column = 0 | ||||||
| @ -433,129 +442,60 @@ function checkSearchSpace(board, searchSpace) | |||||||
|     return true |     return true | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| function backTrace2(board, s) | function findFirstLeastOption(searchSpace) | ||||||
|     local s = s or buildSearchSpace(board) |     local min = 9 | ||||||
|     local x, y = findFirstEmptyCell(board) |     local x, y | ||||||
|     for _, v in ipairs(s[x][y]) do |     for i = 1, 9 do | ||||||
|         local b = cloneBoard(board) |         for j = 1, 9 do | ||||||
|         b[x][y] = v |             local len = #searchSpace[i][j] | ||||||
|         allPairs(b) |             if len > 0 and len < min then | ||||||
|         local ok, finished = checkBoard(b) |                 min = len | ||||||
|         if finished then return b end |                 x = i | ||||||
|         if ok and checkSearchSpace(b) then |                 y = j | ||||||
|             local r = backTrace(b) |  | ||||||
|             if r then return r end |  | ||||||
|         end |  | ||||||
|     end |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| function backTrace3(board, tried) |  | ||||||
|     -- dbg() |  | ||||||
|     local tried = tried or createEmptyBoard() |  | ||||||
|     for x = 1, 9 do |  | ||||||
|         for y = 1, 9 do |  | ||||||
|             if tried[x][y] == 0 and board[x][y] == 0 then |  | ||||||
|                 tried[x][y] = 1 |  | ||||||
|                 print(x, y) |  | ||||||
|                 local s = buildSearchSpace(board) |  | ||||||
|                 for _, v in ipairs(s[x][y]) do |  | ||||||
|                     local b = cloneBoard(board) |  | ||||||
|                     b[x][y] = v |  | ||||||
|                     allPairs(b) |  | ||||||
|                     local ok, finished = checkBoard(b) |  | ||||||
|                     if finished then return b end |  | ||||||
|                     if ok and checkSearchSpace(b) then |  | ||||||
|                         local r = backTrace(b, tried) |  | ||||||
|                         if r then return r end |  | ||||||
|                     end |  | ||||||
|                 end |  | ||||||
|             end |             end | ||||||
|         end |         end | ||||||
|     end |     end | ||||||
|  |     return x, y, min | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| function backTrace4(board, cx, cy) | function backTrace(trace) | ||||||
|     local s = buildSearchSpace(board) |     while true do | ||||||
|     for x = 1, 9 do |         local currentStep = trace[#trace] | ||||||
|         for y = 1, 9 do |         applyFillSinglesRepeatedly(currentStep.board) | ||||||
|             if x ~= cx and y ~=cy then |         local ok, finished = checkBoard(currentStep.board) | ||||||
|                 for _, v in ipairs(s[x][y]) do |         if not ok then rollBack(trace); goto endOfTheLoop end | ||||||
|                     local b= cloneBoard(board) |         if finished then return currentStep.board end | ||||||
|                     b[x][y] = v |         local s = buildSearchSpace(currentStep.board) | ||||||
|                     print(x, y, v) |         ok = checkSearchSpace(currentStep.board, s) | ||||||
|                     -- allPairs(b) |         if not ok then rollBack(trace); goto endOfTheLoop end | ||||||
|                     applyFillSinglesRepeatedly(b) |         if not currentStep.pointer then | ||||||
|                     local ok, finished = checkBoard(b) |             local x, y = findFirstLeastOption(s) | ||||||
|                     if finished then return b end |             currentStep.options = s[x][y] | ||||||
|                     if ok and checkSearchSpace(b) then |             currentStep.pointer = 0 | ||||||
|                         local r = backTrace(b, x, y) |             currentStep.x = x | ||||||
|                         if r then return r end |             currentStep.y = y | ||||||
|                     end |  | ||||||
|                 end |  | ||||||
|             end |  | ||||||
|         end |         end | ||||||
|  |         currentStep.pointer = currentStep.pointer + 1 | ||||||
|  |         if currentStep.pointer > #currentStep.options then rollBack(trace); goto endOfTheLoop end | ||||||
|  |         local nextStep = {} | ||||||
|  |         nextStep.board = cloneBoard(currentStep.board) | ||||||
|  |         nextStep.board[currentStep.x][currentStep.y] = currentStep.options[currentStep.pointer] | ||||||
|  |         trace[#trace+1] = nextStep | ||||||
|  |     ::endOfTheLoop:: | ||||||
|     end |     end | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| function backTrace(board) | function rollBack(trace) | ||||||
|     local s = buildSearchSpace(board) |     assert(#trace > 1, "Something is very wrong!") | ||||||
|     for x = 1, 9 do |     table.remove(trace) | ||||||
|         for y = 1, 9 do |  | ||||||
|             for _, v in ipairs(s[x][y]) do |  | ||||||
|                 local b= cloneBoard(board) |  | ||||||
|                 b[x][y] = v |  | ||||||
|                 -- allPairs(b) |  | ||||||
|                 applyFillSinglesRepeatedly(b) |  | ||||||
|                 local ok, finished = checkBoard(b) |  | ||||||
|                 print(x, y, v, ok, finished) |  | ||||||
|                 showBoard(b) |  | ||||||
|                 io.read(1) |  | ||||||
|                 if finished then return b end |  | ||||||
|                 if ok and checkSearchSpace(b) then |  | ||||||
|                     local r = backTrace(b, x, y) |  | ||||||
|                     if r then return r end |  | ||||||
|                 end |  | ||||||
|             end |  | ||||||
|             return |  | ||||||
|         end |  | ||||||
|     end |  | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| function solve(board) | function solve(board) | ||||||
|     -- allPairs(board) |     local t = {} | ||||||
|     applyFillSinglesRepeatedly(board) |     t[1] = {board=cloneBoard(board),} | ||||||
|     local ok, finished = checkBoard(board) |     return backTrace(t) | ||||||
|     if not ok then print("something's wrong!"); return end |  | ||||||
|     if finished then showBoard(board); return end |  | ||||||
|     local r = backTrace(board) |  | ||||||
|     if r then |  | ||||||
|         showBoard(r) |  | ||||||
|     else |  | ||||||
|         print "Could not solve!" |  | ||||||
|     end |  | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| function sHelper(n) |  | ||||||
|     local fn = string.format("/home/reza/p/lua/22.sudoku/boards/%03d.txt", n) |  | ||||||
|     local board = loadBoard(fn)[1] |  | ||||||
|     solve(board) |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| function checkBoardsEqual(b1, b2) |  | ||||||
|     for i = 1, 9 do |  | ||||||
|         for j = 1, 9 do |  | ||||||
|             if b1[i][j] ~= b2[i][j] then return false end |  | ||||||
|         end |  | ||||||
|     end |  | ||||||
|     return true |  | ||||||
| end |  | ||||||
| 
 |  | ||||||
| -- b = loadBoard("b.txt")[1] |  | ||||||
| -- applyFillSinglesRepeatedly(b) |  | ||||||
| -- s = buildSearchSpace(b) |  | ||||||
| -- allPairs(b) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| return { | return { | ||||||
|     loadBoard = loadBoard, |     loadBoard = loadBoard, | ||||||
|     cloneBoard = cloneBoard, |     cloneBoard = cloneBoard, | ||||||
| @ -566,4 +506,5 @@ return { | |||||||
|     showBoard = showBoard, |     showBoard = showBoard, | ||||||
|     checkBoardsEqual = checkBoardsEqual,  |     checkBoardsEqual = checkBoardsEqual,  | ||||||
|     saveBoard = saveBoard, |     saveBoard = saveBoard, | ||||||
|  |     solve = solve, | ||||||
| } | } | ||||||
|  | |||||||
| @ -433,6 +433,9 @@ function SudokuCanvas:keypressed(key) | |||||||
|         undo(self) |         undo(self) | ||||||
|     elseif key == "f" then |     elseif key == "f" then | ||||||
|         sudoku.saveBoard("lastBoard.txt", self.board[1], self.board[2]) |         sudoku.saveBoard("lastBoard.txt", self.board[1], self.board[2]) | ||||||
|  |     elseif key == "c" then | ||||||
|  |         self.board[2] = sudoku.solve(self.board[1]) | ||||||
|  |         self:checkBoard() | ||||||
|     end |     end | ||||||
|     self.cursor.x = x |     self.cursor.x = x | ||||||
|     self.cursor.y = y |     self.cursor.y = y | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user