Advertisement
OreganoHauch

Funktionierender Sudoku-Generator!!!

Mar 17th, 2023 (edited)
494
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.97 KB | None | 0 0
  1. import itertools
  2. import numpy as np
  3. import random
  4. import time
  5.  
  6. def check_doubles_in_list(liste):
  7. print(f"Length of list: {len(liste)}")
  8. counter = 0
  9. for i, entry in enumerate(liste):
  10. for j, next_entry in enumerate(liste[i+1:len(liste)]):
  11. j += i+1
  12. if entry == next_entry:
  13. print(f"Double found: {entry} (index={i}) == {next_entry} (index={j}))")
  14. counter += 1
  15. print(f"{counter} double entries found.")
  16.  
  17. def conv_console2code(console_output):
  18. char_list = ["np.array("]
  19. for counter, char in enumerate(console_output):
  20. if char != ".":
  21. char_list.append(char)
  22. if char == "." and console_output[counter+1] != "]":
  23. char_list.append(",")
  24. try:
  25. if char == "]" and console_output[counter+1] != "]":
  26. char_list.append(",")
  27. except:
  28. pass
  29. char_list.append(")")
  30. code = "".join(char_list)
  31. print(code)
  32.  
  33. def print_board(board):
  34.  
  35. board = np.asarray(board, dtype="int")
  36.  
  37. end_case1 = " "
  38. end_case2 = " || "
  39.  
  40. first_row = True
  41.  
  42. for row_counter, row in enumerate(board):
  43. if not first_row:
  44. if (row_counter)%3 == 0:
  45. print(15*"= = ")
  46. else:
  47. print("\n")
  48. else:
  49. first_row = False
  50. for col_counter, col in enumerate(row):
  51. if (col_counter+1)%3 == 0:
  52. print(col, end=end_case2)
  53. else:
  54. print(col, end=end_case1)
  55. if col_counter == 8: # end of line
  56. print("\n")
  57.  
  58. def count_nonzero(board):
  59. counter = 0
  60. for row in board:
  61. for num in row:
  62. if num != 0:
  63. counter += 1
  64. return counter
  65.  
  66. def possible(board,num,row,col,printReason=False):
  67.  
  68. # check row
  69. for i in range(9):
  70. if board[row, i] == num:
  71. if printReason:
  72. print(f"{num} tested at {row},{col} --> already in the same row (at col {i})")
  73. return False
  74. # check column
  75. for i in range(9):
  76. if board[i, col] == num:
  77. if printReason:
  78. print(f"{num} tested at {row},{col} --> already in the same col (at row {i})")
  79. return False
  80. # check square
  81. row0 = (row//3)*3
  82. col0 = (col//3)*3
  83. for y in range(row0, row0+3):
  84. for x in range(col0, col0+3):
  85. if board[y,x] == num:
  86. if printReason:
  87. print(f"{num} tested at {row},{col} --> already in the same square (at square with upper left corner {row0}, {col0})")
  88. return False
  89. return True
  90.  
  91. def solveSudoku():
  92.  
  93. global board
  94. global counter
  95. global unique_STOP
  96. global STOP
  97.  
  98. for row in range(9):
  99. for col in range(9):
  100. if board[row,col] == 0:
  101. nums1to9 = np.arange(1,10)
  102. random.shuffle(nums1to9)
  103. for num in nums1to9:
  104. if possible(board, num, row, col):
  105. board[row,col] = num
  106. solveSudoku()
  107. if not unique_STOP:
  108. if not STOP:
  109. board[row,col] = 0 # try new possibilities (non-unique Sudoku)
  110. return # backtracking (empty field, but no number fits) --> does not print out the "wrong" Sudoku
  111. counter += 1
  112.  
  113. '''if not suppress_print:
  114. # Check if Sudoku is the same
  115. if counter == 1:
  116. if np.array_equal(first_sudoku, board):
  117. print("Sudoku is not solvable/over-constrained!")
  118. return
  119.  
  120. if not suppress_print:
  121. print(f"Solution #{counter}:\n")
  122. print(board, "\n")
  123.  
  124. ## PREVENT CPU OVERLOAD ##
  125. if counter > 100:
  126. return'''
  127. STOP = True
  128. return board
  129.  
  130. def createSudoku():
  131.  
  132. global board
  133. global counter
  134. global unique_STOP
  135. global STOP
  136.  
  137. whileTrue_counter1 = 0
  138. while True:
  139. board = np.zeros((9,9))
  140. position = 1
  141. BREAK_for_loop = False
  142. x = 70
  143. for i in range(x):
  144. #convert position to coordinate
  145. col = (position-1)%9
  146. row = (position-1)//9
  147. whileTrue_counter2 = 0
  148. while True:
  149. num = random.randint(1,9)
  150. if possible(board, num, row, col):
  151. board[row,col] = num
  152. #print(f"{num} inserted at position ({row}, {col}). Still {x-1-i} entries left to fill.")
  153. break
  154. whileTrue_counter2 += 1
  155. if whileTrue_counter2 > 100:
  156. BREAK_for_loop = True
  157. break
  158. if BREAK_for_loop:
  159. #print(f"Rare case occurred! {x} numbers couldn't be placed randomly according to Sudoku rules. New attempt...")
  160. break
  161. position += 1
  162.  
  163. unique_STOP = False
  164. STOP = False
  165. if not BREAK_for_loop:
  166. counter = 0
  167. #print(first_sudoku)
  168. solveSudoku()
  169. if counter == 1:
  170. #print("Found unique Sudoku!!!")
  171. break
  172. if counter > 1:
  173. print(f"counter for unique sudoku > 1, it is: {counter}", end=", ")
  174. whileTrue_counter1 += 1
  175. if whileTrue_counter1 in [10, 100, 1000, 10000, 100000, 200000, 300000]:
  176. print(f"{whileTrue_counter1}th attempt to find unique Sudoku...")
  177. # print("---")
  178. # print(sudoku)
  179. # print("----")
  180. ## user selects difficulty level
  181. while True:
  182. numClues_input = input("Choose difficulty level:\n1) Extremely easy\n2) Easy\n3) Medium\n4) Difficult\n5) Evil\n\n--> ")
  183. if numClues_input.lower() in ["1", "1)", "one", "eins", "i", "extremely easy"]:
  184. numClues = random.randint(47,80)
  185. break
  186. elif numClues_input.lower() in ["2", "2)", "two", "zwei", "ii", "easy"]:
  187. numClues = random.randint(36,46)
  188. break
  189. elif numClues_input.lower() in ["3", "3)", "three", "drei", "iii", "medium"]:
  190. numClues = random.randint(32,35)
  191. break
  192. elif numClues_input.lower() in ["4", "4)", "four", "vier", "iv", "difficult"]:
  193. numClues = random.randint(28,31)
  194. break
  195. elif numClues_input.lower() in ["5", "5)", "five", "fünf", "v", "evil"]:
  196. numClues = random.randint(17,27)
  197. break
  198. print("\nSelect difficulty level...\n")
  199.  
  200. print(f"\nYou have selected difficulty level {numClues_input}. Therefore you will get {numClues} clues.\n")
  201.  
  202. numRemoveClues = 81-numClues
  203.  
  204. ## remove up to 81-17=64 clues until there is a unique solution
  205. allCoordinates = list(itertools.product(range(0,9), repeat=2))
  206.  
  207. while_counter = 0
  208. start = time.time()
  209. SAVE_board = board.copy()
  210. while True:
  211. board = SAVE_board.copy()
  212. removeCoordinates = random.sample(allCoordinates, numRemoveClues)
  213. for coord in removeCoordinates:
  214. row = coord[0]
  215. col = coord[1]
  216. board[row, col] = 0
  217. counter = 0
  218. board_removedStuff = board.copy()
  219. solveSudoku()
  220. if counter == 1:
  221. print_board(board_removedStuff)
  222. return board_removedStuff
  223. if counter > 1:
  224. print(f"L{counter}", end=", ")
  225.  
  226. while_counter += 1
  227. if while_counter in [10,100,1000,10000,100000,1000000]:
  228. print(f"{while_counter} Sudokus with {numClues} clues have been found so far, but none of them is unique...")
  229. stop = time.time()
  230. elapsed_time = stop-start
  231. if elapsed_time > 120:
  232. print("Time elapsed has exceed the maximum waiting time of 120s.")
  233. break
  234.  
  235. board = createSudoku()
  236. counter=0
  237. solveSudoku()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement