Advertisement
OreganoHauch

CreateSudokus

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