woodsja

Untitled

Dec 18th, 2018
382
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.01 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. import copy
  17.  
  18.  
  19. # In[3]:
  20.  
  21.  
  22. # global to keep track of the number of backtracks necessary
  23. limit = 10000
  24. backtracks = 0
  25.  
  26.  
  27. # In[5]:
  28.  
  29.  
  30. def findNextCellToFill(grid):
  31.     # Takes a 9 by 9 grid and looks row by column for the first zero.
  32.     # Returns either x, y coordinates of first '0' or -1, -1
  33.     for x in range(0, 9):
  34.         for y in range(0, 9):
  35.             if grid[x][y] == 0:
  36.                 return x, y
  37.     return -1, -1
  38.  
  39.  
  40. # In[6]:
  41.  
  42.  
  43. def isValid(grid, i, j, e):
  44.     # 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''
  45.     # returns True if passes row/column/sector checks.
  46.     # returns False otherwise
  47.     rowOk = all([e != grid[i][x] for x in range(9)])
  48.     if rowOk:
  49.         columnOk = all([e != grid[x][j] for x in range(9)])
  50.         if columnOk:
  51.             # find the top left x, y coordinate of section containing the i,j cell
  52.             secTopX, secTopY = 3*(i//3), 3*(j//3)
  53.             for x in range(secTopX, secTopX+3):
  54.                 for y in range(secTopY, secTopY+3):
  55.                     if grid[x][y] == e:
  56.                         return False
  57.             return True
  58.     return False
  59.  
  60.  
  61. # In[7]:
  62.  
  63.  
  64. def makeRandomSudoku(number_of_randoms):
  65.     # generates a random board with no constraints
  66.     # board has number_of_randoms filled in values with all other values as zero
  67.     grid_list = [0]*81
  68.     locations = np.random.choice(81, number_of_randoms, replace=False)
  69.     for location in locations:
  70.             grid_list[location] = int(np.random.randint(1,high=10))
  71.    
  72.     i = 0
  73.     grid = []
  74.     while i < len(grid_list):
  75.         grid.append(grid_list[i:i+9])
  76.         i+=9
  77.     return grid
  78.  
  79.  
  80. # In[8]:
  81.  
  82.  
  83. def solveSudoku(grid, i=0, j=0):
  84.     # fills in missing squares of Sudoku puzzle using rules with a brute-force guess/check
  85.     # takes a grid and starts looking in the top left corner i,j = 0,0
  86.     global limit
  87.     global backtracks
  88.     if backtracks < limit:
  89.         i, j = findNextCellToFill(grid)
  90.         if i == -1:
  91.             # we solved it or there's nothing left to solve
  92.             return True
  93.  
  94.         for e in range (1, 10):
  95.             # try different values in i, j location
  96.             if isValid(grid, i, j, e):
  97.                 grid[i][j] = e
  98.                 if solveSudoku(grid, i, j):
  99.                     return True
  100.  
  101.                 # undo current cell for backtracking
  102.                 if backtracks < limit:
  103.                     backtracks += 1
  104.                     grid[i][j] = 0
  105.         else:
  106.             # loop fell through without filling a number
  107.             return False
  108.  
  109.  
  110.  
  111.     else:
  112.         return False
  113.  
  114.        
  115.    
  116.  
  117.  
  118. # In[9]:
  119.  
  120.  
  121. def printSudoku(grid):
  122.     numrow = 0
  123.     for row in grid:
  124.         if numrow % 3 == 0 and numrow != 0:
  125.             print(' ')
  126.         print(row[0:3], ' ', row[3:6], ' ', row[6:9])
  127.         numrow += 1
  128.     return
  129.  
  130.  
  131. # In[10]:
  132.  
  133.  
  134. def process_input(grid):
  135.     # converts a grid into a flat list with one-hot encoding
  136.     onehot_encoded = list()
  137.     flat_grid = [item for sublist in grid for item in sublist]
  138.     for value in flat_grid:
  139.         temp = [0 for _ in range(10)]
  140.         temp[value - 1] = 1
  141.         onehot_encoded.append(temp)
  142.     #flat_onehot_grid = [item for sublist in onehot_encoded for item in sublist]
  143.     return onehot_encoded
  144.  
  145.  
  146. # In[11]:
  147.  
  148.  
  149. def build_dataset(number_of_datapoints, number_of_randoms):
  150.     # takes an int, number_of_datapoints, and builds a dataset of solvable Sudoku grids
  151.     # each test_grid will have number_of_randoms constraints
  152.     test_grid
  153.     test_grid = makeRandomSudoku(number_of_randoms)
  154.    
  155.  
  156.  
  157. # In[12]:
  158.  
  159.  
  160. def generate_pair():
  161.     global backtracks
  162.     # generates an unsolved and solved grid
  163.     backtracks = 0
  164.     solved = makeRandomSudoku(20)
  165.     unsolved = copy.deepcopy(solved)
  166.     if solveSudoku(solved):
  167.         return unsolved, solved
  168.     else:
  169.         backtracks = 0
  170.         return generate_pair()
  171.  
  172.  
  173. # In[ ]:
  174.  
  175.  
  176. import time
  177. data = []
  178.  
  179. start = time.time()
  180. for pair in range(5):
  181.     data1, data2 = generate_pair()
  182.     data.append([data1, data2])
  183. end = time.time()
  184. print(end-start)
  185.  
  186.  
  187. # In[ ]:
  188.  
  189.  
  190. printSudoku(data[0][0])
  191. print('\n')
  192. printSudoku(data[0][1])
  193.  
  194.  
  195. # In[ ]:
  196.  
  197.  
  198. def save_data(data):
  199.     with open("Sudoku_data.txt", 'w') as f:
  200.         for pair in data:
  201.             for grid in pair:
  202.                 for row in grid:
  203.                     for column in row:
  204.                         f.write("%i\n" % column)
Advertisement
Add Comment
Please, Sign In to add comment