woodsja

sudoku

Dec 11th, 2018
450
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.87 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # coding: utf-8
  3.  
  4. # In[1]:
  5.  
  6.  
  7. # sections of code borrowed from "You will Never Want to Play Sudoku Again" by Srini Devadas
  8. # https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-s095-programming-for-the-puzzled-january-iap-2018/puzzle-8-you-wont-want-to-play-sudoku-again/sudoku.py
  9. # Whatever license Srini chose applies to the code he or his grad students wrote. Standard MIT license applies to anything else that I wrote.
  10.  
  11.  
  12. # In[2]:
  13.  
  14.  
  15. import numpy as np
  16.  
  17.  
  18. # In[3]:
  19.  
  20.  
  21. # global to keep track of the number of backtracks necessary
  22. limit = 10000
  23. backtracks = 0
  24.  
  25.  
  26. # In[5]:
  27.  
  28.  
  29. def findNextCellToFill(grid):
  30.     # Takes a 9 by 9 grid and looks row by column for the first zero.
  31.     # Returns either x, y coordinates of first '0' or -1, -1
  32.     for x in range(0, 9):
  33.         for y in range(0, 9):
  34.             if grid[x][y] == 0:
  35.                 return x, y
  36.     return -1, -1
  37.  
  38.  
  39. # In[6]:
  40.  
  41.  
  42. def isValid(grid, i, j, e):
  43.     # takes a 9 by 9 grid; i,j coordinates; and a number 'e' then looks row-wise, column-wise, and sector-wise for duplicates of the number 'e''
  44.     # returns True if passes row/column/sector checks.
  45.     # returns False otherwise
  46.     rowOk = all([e != grid[i][x] for x in range(9)])
  47.     if rowOk:
  48.         columnOk = all([e != grid[x][j] for x in range(9)])
  49.         if columnOk:
  50.             # find the top left x, y coordinate of section containing the i,j cell
  51.             secTopX, secTopY = 3*(i//3), 3*(j//3)
  52.             for x in range(secTopX, secTopX+3):
  53.                 for y in range(secTopY, secTopY+3):
  54.                     if grid[x][y] == e:
  55.                         return False
  56.             return True
  57.     return False
  58.  
  59.  
  60. # In[7]:
  61.  
  62.  
  63. def makeRandomSudoku(number_of_randoms):
  64.     # generates a random board with no constraints
  65.     # board has number_of_randoms filled in values with all other values as zero
  66.     grid_list = [0]*81
  67.     locations = np.random.choice(81, number_of_randoms, replace=False)
  68.     for location in locations:
  69.             grid_list[location] = int(np.random.randint(1,high=10))
  70.    
  71.     i = 0
  72.     grid = []
  73.     while i < len(grid_list):
  74.         grid.append(grid_list[i:i+9])
  75.         i+=9
  76.     return grid
  77.  
  78.  
  79. # In[8]:
  80.  
  81.  
  82. def solveSudoku(grid, i=0, j=0):
  83.     # fills in missing squares of Sudoku puzzle using rules with a brute-force guess/check
  84.     # takes a grid and starts looking in the top left corner i,j = 0,0
  85.     global limit
  86.     global backtracks
  87.     if backtracks < limit:
  88.         i, j = findNextCellToFill(grid)
  89.         if i == -1:
  90.             # we solved it or there's nothing left to solve
  91.             return True
  92.  
  93.         for e in range (1, 10):
  94.             # try different valies in i, j location
  95.             if isValid(grid, i, j, e):
  96.                 grid[i][j] = e
  97.                 if solveSudoku(grid, i, j):
  98.                     return True
  99.  
  100.                 # undo current cell for backtracking
  101.                 if backtracks < limit:
  102.                     backtracks += 1
  103.                     grid[i][j] = 0
  104.                 else:
  105.                     return False            
  106.     else:
  107.         return False    
  108.  
  109.  
  110. # In[9]:
  111.  
  112.  
  113. def printSudoku(grid):
  114.     numrow = 0
  115.     for row in grid:
  116.         if numrow % 3 == 0 and numrow != 0:
  117.             print(' ')
  118.         print(row[0:3], ' ', row[3:6], ' ', row[6:9])
  119.         numrow += 1
  120.     return
  121.  
  122.  
  123. # In[10]:
  124.  
  125.  
  126. def process_input(grid):
  127.     # converts a grid into a flat list with one-hot encoding
  128.     onehot_encoded = list()
  129.     flat_grid = [item for sublist in grid for item in sublist]
  130.     for value in flat_grid:
  131.         temp = [0 for _ in range(10)]
  132.         temp[value - 1] = 1
  133.         onehot_encoded.append(temp)
  134.     #flat_onehot_grid = [item for sublist in onehot_encoded for item in sublist]
  135.     return onehot_encoded
  136.  
  137.  
  138. # In[11]:
  139.  
  140.  
  141. def build_dataset(number_of_datapoints, number_of_randoms):
  142.     # takes an int, number_of_datapoints, and builds a dataset of solvable Sudoku grids
  143.     # each test_grid will have number_of_randoms constraints
  144.     test_grid
  145.     test_grid = makeRandomSudoku(number_of_randoms)
  146.    
  147.  
  148.  
  149. # In[12]:
  150.  
  151.  
  152. import tensorflow as tf
  153. print(tf.__version__)
  154. tf.enable_eager_execution()
  155.  
  156.  
  157. # In[51]:
  158.  
  159.  
  160. def generate_pair():
  161.     global backtracks
  162.     # generates an unsolved and solved grid
  163.     solved = makeRandomSudoku(5)
  164.     unsolved = solved[:][:]
  165.     if solveSudoku(solved):
  166.         print(id(unsolved))
  167.         print(id(solved))
  168.         return unsolved, solved
  169.     elif solveSudoku(solved) is None:
  170.         pass
  171.     else:
  172.         backtracks = 0
  173.         solved = makeRandomSudoku(5)
  174.         unsolved = solved[:][:]
  175.         generate_pair()
  176.  
  177.  
  178. # In[14]:
  179.  
  180.  
  181. backtracks = 0
  182. solved = makeRandomSudoku(15)
  183. printSudoku(solved)
  184. if solveSudoku(solved):
  185.     print('\n')
  186.     printSudoku(solved)
  187.  
  188.  
  189. # In[63]:
  190.  
  191.  
  192. backtracks = 0
  193. asdf1, asdf2 = generate_pair()
Advertisement
Add Comment
Please, Sign In to add comment