Advertisement
vovkakorben

sudoku_solve.py

Nov 28th, 2021
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.64 KB | None | 0 0
  1. import time,copy
  2.  
  3. #check row is correct sudoku row ----------------------------------------------
  4. def check_row(m,x,y,dx,dy):
  5.     t = {1:0, 2:0, 3:0, 4:0, 5:0}
  6.     for i in range(size):
  7.         t[abs(m[y][x])] += 1
  8.         x += dx
  9.         y += dy
  10.     for i in range(1,size+1):
  11.         if (t[i] != 1):
  12.             return False
  13.     return True
  14.  
  15.  
  16. # check matrix is right sudoku ------------------------------------------------
  17. def check_matrix(m):
  18.     for i in range(size):
  19.         if not check_row(m,i,0,0,1): # column
  20.             return False
  21.         if not check_row(m,0,i,1,0): # row
  22.             return False
  23.     if not (check_row(m,0,0,1,1)): # top-left diagonal
  24.         return False
  25.     if not (check_row(m,0,4,1,-1)): # bottom-left diagonal
  26.         return False
  27.     return True
  28.  
  29. # this one find avialable nums for cell ---------------------------------------
  30. def get_range_for_cell(m,x,y):
  31.     r = [1,2,3,4,5]
  32.     for j in range(size):
  33.         try:
  34.             i = r.index(abs(m[y][j]))
  35.         except ValueError: pass
  36.         else: del r[i]
  37.         try:
  38.             i = r.index(abs(m[j][x]))
  39.         except ValueError: pass
  40.         else: del r[i]
  41.     return r
  42.  
  43. # main solve routine ----------------------------------------------------------
  44. def solve(m):
  45.     mout = copy.deepcopy(m)
  46.     tmr = time.time()
  47.     try:
  48.         d = []
  49.         modified = 0
  50.         while (True):
  51.             for y in range(size):
  52.                 for x in range(size):
  53.                     if (m[y][x] <= 0):
  54.                         rng = get_range_for_cell(mout,x,y) # searching possible variants for cell
  55.                         if len(rng) == 1:
  56.                             mout[y][x] = -(rng[0]) # just one variant - put it
  57.                             modified += 1
  58.                         elif len(rng) > 1:
  59.                             d.append({'x':x, 'y':y, 'range':rng, 'pos':0 }) # put variants and set pointer to zero
  60.             if (modified == 0):
  61.                 break  
  62.             modified = 0  
  63.             d.clear()
  64.  
  65.         # check variant count        
  66.         variant_count = 1
  67.         for x in d:
  68.             variant_count *= len(x['range'])
  69.         #print(f'Variants: {variant_count}')
  70.         if (variant_count>50000):
  71.             return [-2,f'Too much variants({variant_count})']
  72.  
  73.         if (variant_count == 1):
  74.             if (check_matrix(mout) == False):
  75.                 return [-1,'Just one incorrect solve :(']
  76.             else:
  77.                 return [0,mout]
  78.         while (True):
  79.  
  80.             #paste values
  81.             for v1 in d:
  82.                 mout[v1['y']][v1['x']] = -(v1['range'][v1['pos']])
  83.  
  84.             #check matrix for done
  85.             if (check_matrix(mout) == True):
  86.                 return [0,mout]
  87.  
  88.             #iterate values
  89.             vc = 0
  90.             for vc in range(len(d)):
  91.                 d[vc]['pos'] += 1
  92.                 if (d[vc]['pos'] == len(d[vc]['range'])):
  93.                     d[vc]['pos'] = 0
  94.                 #check is last item reseted
  95.                     if (vc == len(d)):
  96.                         break
  97.                 else:
  98.                     break
  99.  
  100.         return [-3,False]
  101.     finally:
  102.         pass
  103.         #tmr = time.time()-tmr
  104.         #print(f"Total taken: {tmr:.5f}s")
  105.         #print(f"Per try: {(tmr/variant_count):.5f}s")
  106.  
  107. """
  108. matrix = [
  109. [5,1,3,2,4],
  110. [0,0,0,0,0],
  111. [0,0,0,0,0],
  112. [0,0,0,0,0],
  113. [2,4,5,1,3]]
  114.  
  115.  
  116. matrix = [
  117.    [5,1,0,2,0],
  118.    [0,0,0,5,1],
  119.    [4,5,1,0,0],
  120.    [0,0,0,4,5],
  121.    [0,4,5,0,3]]
  122. matrix = [
  123.    [0,1,0,2,0],
  124.    [0,0,0,5,1],
  125.    [4,5,0,0,0],
  126.    [0,0,0,4,5],
  127.    [0,4,5,0,0]]
  128.  
  129.  
  130. print(solve(matrix))
  131.  
  132. """
  133. size = 5
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement