Advertisement
AceFaiuh

Python Sudoku Code

May 14th, 2013
224
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ===================================================================================================================
  2. Input/Output
  3. ===================================================================================================================
  4. IN:
  5. 059000483
  6. 000000012
  7. 010028000
  8. 098074020
  9. 040080030
  10. 070630540
  11. 000160050
  12. 620000000
  13. 735000860
  14.  
  15. OUT:
  16. 2 5 9 7 1 6 4 8 3
  17. 0 6 0 0 0 0 0 1 2
  18. 0 1 6 0 2 8 0 0 0
  19. 0 9 8 0 7 4 0 2 0
  20. 0 4 0 0 8 0 0 3 0
  21. 0 7 0 6 3 0 5 4 8
  22. 0 8 0 1 6 0 0 5 0
  23. 6 2 0 0 0 0 0 0 0
  24. 7 3 5 0 0 0 8 6 0
  25.  
  26. ===================================================================================================================
  27. Main Function - Fixed Version
  28. ===================================================================================================================
  29.  
  30. from TestListQ3 import testSudoku
  31. state = []
  32. def toIntList2D(lst):
  33.     """Function that works with a 2D list as the parameter\nIt returns the list as a list of integers"""
  34.     newLst = []
  35.     for i in range(9):
  36.         newLst.append([int(lst[i][j]) for j in range(9)])
  37.     return newLst
  38.  
  39. def toIntList(lst):
  40.     """Takes a list as the parameter\nIt returns the list as a list of integers"""
  41.     return [int(lst[i]) for i in range(9) if type(lst[i])==str]
  42.  
  43. def inCol(gridN, i, colN):
  44.     """Searches for int i in a column"""
  45.     if i in makeCol(gridN, colN):
  46.         return True
  47.     else:
  48.         return False
  49.  
  50. def makeCol(gridN, colN):
  51.     """Creates the column grid from the grid\nReturns the column grid"""
  52.     vertGrid = []
  53.     for x in range(9):
  54.         placeholder=[]
  55.         for y in range(9):
  56.             placeholder.append(gridN[y][x])
  57.         vertGrid.append(placeholder)
  58.     return vertGrid[colN-1]
  59.  
  60. def inSquare(nGrid,i, rowN, colN):
  61.     """Searches for int i in a grid area"""
  62.     if i in makeSquare(nGrid, rowN, colN):
  63.         return True
  64.     else:
  65.         return False
  66.  
  67. def makeSquare(nGrid, rowN, colN):
  68.     """Creates the specified block from the grid\nReturns the block"""
  69.     newTest =[]    
  70.     newLst = []
  71.    
  72.     for i in range(9):
  73.         newLst.append([str(nGrid[i][j]) for j in range(9)])
  74.     nGrid = newLst
  75.     threeby3 = [[] for i in range(3)]
  76.     for i in range(9):
  77.         newTest.append("".join(nGrid[i]))
  78.         for j, s, e in zip(range(3), [0,3,6], [3,6,9]):
  79.             threeby3[j].append(newTest[i][s:e])
  80.  
  81.     final = [[] for i in range(9)]
  82.     for i,j in zip(range(9),[0,1,2]*3):
  83.         if i<=2:
  84.             final[i] = threeby3[j][0:3]
  85.         elif 3<=i<=5:
  86.             final[i] = threeby3[j][3:6]
  87.         elif 6<=i<=8:
  88.             final[i] = threeby3[j][6:9]
  89.     return final[determineBlock(rowN, colN)-1]
  90.  
  91. def determineBlock(rowN, colN):
  92.     """Determines which block the number is in"""
  93.     a,b,c = [1,2,3],[4,5,6],[7,8,9]
  94.     if rowN in a and colN in a:
  95.         return 1
  96.     elif rowN in a and colN in b:
  97.         return 2
  98.     elif rowN in a and colN in c:
  99.         return 3
  100.     elif rowN in b and colN in a:
  101.         return 4
  102.     elif rowN in b and colN in b:
  103.         return 5
  104.     elif rowN in b and colN in c:
  105.         return 6
  106.     elif rowN in c and colN in a:
  107.         return 7
  108.     elif rowN in c and colN in b:
  109.         return 8
  110.     elif rowN in c and colN in c:
  111.         return 9
  112.  
  113. def populate(grid):
  114.     """Populates the grid by generating values and testing them for each position"""
  115.     nGrid = []
  116.     for i in range(9):
  117.         nGrid.append([int(grid[i][j]) for j in range(9)])
  118.     for i in range(9): # Rows
  119.         rowSet = set(nGrid[i]) #Creates a unique list of numbers from each row
  120.         if 0 in rowSet:
  121.             rowSet.remove(0)
  122.         for j in range(9): #Columns
  123.             toAdd=[]
  124.             if nGrid[i][j] ==0:
  125.                 # Creates a unique set of numbers from 1-9 that aren't in the row, column or 3X3 Square
  126.                 for k in [op for op in range(1,10) if op not in rowSet and (inCol(nGrid, op, j+1)==False and inSquare(nGrid, op, i+1, j+1)==False)]:
  127.                     toAdd.append(k)
  128.             if len(toAdd)==1:# If there is only one value in that list, it adds it to the grid
  129.                 nGrid[i][j]=toAdd[0]
  130.                 toAdd = []
  131.             elif len(toAdd)!=0:
  132.                 print("Row:",i,"Col:",j,"toAdd:",toAdd)
  133.                 finalCheck = additionalCheck(nGrid, toAdd, i+1, j+1)
  134.                 if finalCheck!=False and finalCheck!=0:
  135.                     nGrid[i][j] = finalCheck
  136.                     finalCheck = 0
  137.     print()
  138.     print("Old: ")
  139.     printGrid(toIntList2D(grid))
  140.     print("New: ")
  141.     printGrid(toIntList2D(nGrid))
  142.     return nGrid
  143.  
  144.  
  145. def additionalCheck(grid, toCheck, rowN, colN):
  146.     """The final check before moving on the the next square"""
  147.     rowCol = [[1,2,3],[4,5,6],[7,8,9]]
  148.     nRow, nCol = 0,0
  149.     toAd=[]
  150.     for i in range(len(rowCol)):
  151.         if rowN in rowCol[i]:
  152.             setRC = set(rowCol[i])
  153.             setRC.remove(rowN)
  154.             nRow = list(setRC)
  155.         if colN in rowCol[i]:
  156.             setRC = set(rowCol[i])
  157.             setRC.remove(colN)
  158.             nCol = list(setRC)
  159.     for k in toCheck:
  160.         if (k in grid[nRow[0]-1]) and (k in grid[nRow[1]-1]) and (inCol(grid, k, nCol[0])==True and inCol(grid, k, nCol[1])==True) and k not in grid[rowN] and inCol(grid, k, colN)==False:
  161.             toAd.append(k)
  162.     if len(toAd)==1:
  163.         return toAd[0]
  164.     else:
  165.         return False
  166.  
  167.  
  168. def printGrid(grid):
  169.     """Prints the grid in a user friendly format"""
  170.     for i in range(len(grid)):
  171.         print(" ".join([str(k) for k in grid[i]]))
  172.  
  173.  
  174. def main():
  175.     fi = open("sudoku.txt", "r")
  176.     inFile = fi.read()
  177.     grid = [list(i) for i in inFile.split("\n")]
  178.     if testSudoku(grid)==True:
  179.         printGrid(grid)
  180.     else:
  181.         while True:
  182.             newGrid = populate(grid)
  183.             grid=newGrid[:]
  184.             if testSudoku(grid)==True:
  185.                 printGrid(grid)
  186.                 break
  187.        
  188. main()
  189.  
  190.  
  191. ===================================================================================================================
  192. Test Function
  193. ===================================================================================================================
  194.  
  195. def testSudoku(testGrid):#HORIZONTAL CHECK
  196.     for i in testGrid:
  197.         if len(set(i))!=9:
  198.             return False
  199.            
  200.     #CREATE VERTICAL
  201.     vertGrid = []
  202.     for x in range(9):
  203.         placeholder=[]
  204.         for y in range(9):
  205.             placeholder.append(testGrid[y][x])
  206.         vertGrid.append(placeholder)
  207.        
  208.        
  209.     #VERTICAL CHECK
  210.     for i in vertGrid:
  211.         if len(set(i))!=9:
  212.             return False
  213.            
  214.     #CHECK 3X3
  215.     ##Join
  216.     newTest =[]
  217.     threeby3 = list([] for i in range(9))
  218.     for i in range(9):
  219.         newTest.append("".join(testGrid[i]))
  220.         for j, s, e in zip(range(3), [0,3,6], [3,6,9]):
  221.             threeby3[i].append(newTest[i][s:e])
  222.         "".join(threeby3[i])
  223.  
  224.     for i in threeby3:
  225.         if len(set("".join(i)))!=9:
  226.             return False
  227.    
  228.     return True
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement