Advertisement
OreganoHauch

CreateSudokus_v2

Jan 19th, 2023
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.83 KB | None | 0 0
  1. import itertools
  2. import numpy as np
  3. import random
  4. import time
  5.  
  6. def possible(board,num,row,col, printReason=False):
  7.  
  8. # check row
  9. for i in range(9):
  10. if board[row, i] == num:
  11. if printReason:
  12. print(f"{num} tested at {row},{col} --> already in the same row (at col {i})")
  13. return False
  14. # check column
  15. for i in range(9):
  16. if board[i, col] == num:
  17. if printReason:
  18. print(f"{num} tested at {row},{col} --> already in the same col (at row {i})")
  19. return False
  20. # check square
  21. row0 = (row//3)*3
  22. col0 = (col//3)*3
  23. for y in range(row0, row0+3):
  24. for x in range(col0, col0+3):
  25. if board[y,x] == num:
  26. if printReason:
  27. print(f"{num} tested at {row},{col} --> already in the same square (at square with upper left corner {row0}, {col0})")
  28. return False
  29. return True
  30.  
  31. def solveSudoku(board, random_nums, onlyFirstSolution, suppress_print):
  32.  
  33. global counter
  34.  
  35. for row in range(9):
  36. for col in range(9):
  37. if board[row,col] == 0:
  38. nums1to9 = np.arange(1,10)
  39. if random_nums:
  40. random.shuffle(nums1to9)
  41. for num in nums1to9:
  42. if possible(board, num, row, col):
  43. board[row,col] = num
  44. solveSudoku(board,random_nums,onlyFirstSolution,suppress_print)
  45. board[row,col] = 0 # try new possibilities (non-unique Sudoku)
  46. return # backtracking (empty field, but no number fits) --> does not print out the "wrong" Sudoku
  47.  
  48. counter += 1
  49.  
  50. if not suppress_print:
  51. # Check if Sudoku is the same
  52. if counter == 1:
  53. try:
  54. if np.array_equal(first_sudoku, board):
  55. print("Sudoku is not solvable/over-constrained!")
  56. return
  57. except:
  58. print("Define the variable first_sudoku.")
  59.  
  60. if onlyFirstSolution:
  61. return board
  62.  
  63. if not suppress_print:
  64. print(f"Solution #{counter}:\n")
  65. print(board, "\n")
  66.  
  67. if onlyFirstSolution:
  68. return board
  69.  
  70. ## PREVENT CPU OVERLOAD ##
  71. if counter > 100:
  72. return
  73.  
  74. return board
  75.  
  76. def createSudoku():
  77.  
  78. global counter
  79. global first_sudoku
  80.  
  81. sudoku = np.zeros((9,9))
  82. first_sudoku = sudoku.copy()
  83. counter = 0
  84. sudoku = solveSudoku(board=first_sudoku, random_nums=True, onlyFirstSolution=True, suppress_print=True)
  85. print("---")
  86. print(sudoku)
  87. print("----")
  88. ## user selects difficulty level
  89. while True:
  90. numClues_input = input("Choose difficulty level:\n1) Extremely easy\n2) Easy\n3) Medium\n4) Difficult\n5) Evil\n\n--> ")
  91. if numClues_input.lower() in ["1", "1)", "one", "eins", "i", "extremely easy"]:
  92. numClues = random.randint(47,80)
  93. break
  94. elif numClues_input.lower() in ["2", "2)", "two", "zwei", "ii", "easy"]:
  95. numClues = random.randint(36,46)
  96. break
  97. elif numClues_input.lower() in ["3", "3)", "three", "drei", "iii", "medium"]:
  98. numClues = random.randint(32,35)
  99. break
  100. elif numClues_input.lower() in ["4", "4)", "four", "vier", "iv", "difficult"]:
  101. numClues = random.randint(28,31)
  102. break
  103. elif numClues_input.lower() in ["5", "5)", "five", "fünf", "v", "evil"]:
  104. numClues = random.randint(17,27)
  105. break
  106. print("\nSelect difficulty level...\n")
  107.  
  108. print(f"\nYou have selected difficulty level {numClues_input}. Therefore you will get {numClues} clues.")
  109.  
  110. numRemoveClues = 81-numClues
  111.  
  112. ## remove up to 81-17=64 clues until there is a unique solution
  113. allCoordinates = list(itertools.product(range(0,9), repeat=2))
  114.  
  115. while_counter = 0
  116. start = time.time()
  117. while True:
  118. removeCoordinates = random.choices(allCoordinates, k=numRemoveClues)
  119. for coord in removeCoordinates:
  120. row = coord[0]
  121. col = coord[1]
  122. sudoku[row, col] = 0
  123. counter = 0
  124. sudoku = solveSudoku(board=first_sudoku, random_nums=True, onlyFirstSolution=False, suppress_print=True)
  125. if counter == 1:
  126. return sudoku
  127.  
  128. while_counter += 1
  129. if while_counter in [10,100,1000,10000,100000,1000000]:
  130. print(f"{while_counter} Sudokus with {numClues} clues have been found so far, but none of them is unique...")
  131. stop = time.time()
  132. elapsed_time = stop-start
  133. if elapsed_time > 120:
  134. print("Time elapsed has exceed the maximum waiting time of 120s.")
  135. break
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement