Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import itertools
- import numpy as np
- import random
- import time
- def possible(board,num,row,col, printReason=False):
- # check row
- for i in range(9):
- if board[row, i] == num:
- if printReason:
- print(f"{num} tested at {row},{col} --> already in the same row (at col {i})")
- return False
- # check column
- for i in range(9):
- if board[i, col] == num:
- if printReason:
- print(f"{num} tested at {row},{col} --> already in the same col (at row {i})")
- return False
- # check square
- row0 = (row//3)*3
- col0 = (col//3)*3
- for y in range(row0, row0+3):
- for x in range(col0, col0+3):
- if board[y,x] == num:
- if printReason:
- print(f"{num} tested at {row},{col} --> already in the same square (at square with upper left corner {row0}, {col0})")
- return False
- return True
- def solveSudoku(board, random_nums, onlyFirstSolution, suppress_print):
- global counter
- for row in range(9):
- for col in range(9):
- if board[row,col] == 0:
- nums1to9 = np.arange(1,10)
- if random_nums:
- random.shuffle(nums1to9)
- for num in nums1to9:
- if possible(board, num, row, col):
- board[row,col] = num
- solveSudoku(board,random_nums,onlyFirstSolution,suppress_print)
- board[row,col] = 0 # try new possibilities (non-unique Sudoku)
- return # backtracking (empty field, but no number fits) --> does not print out the "wrong" Sudoku
- counter += 1
- if not suppress_print:
- # Check if Sudoku is the same
- if counter == 1:
- try:
- if np.array_equal(first_sudoku, board):
- print("Sudoku is not solvable/over-constrained!")
- return
- except:
- print("Define the variable first_sudoku.")
- if onlyFirstSolution:
- return board
- if not suppress_print:
- print(f"Solution #{counter}:\n")
- print(board, "\n")
- if onlyFirstSolution:
- return board
- ## PREVENT CPU OVERLOAD ##
- if counter > 100:
- return
- return board
- def createSudoku():
- global counter
- global first_sudoku
- sudoku = np.zeros((9,9))
- first_sudoku = sudoku.copy()
- counter = 0
- sudoku = solveSudoku(board=first_sudoku, random_nums=True, onlyFirstSolution=True, suppress_print=True)
- print("---")
- print(sudoku)
- print("----")
- ## user selects difficulty level
- while True:
- numClues_input = input("Choose difficulty level:\n1) Extremely easy\n2) Easy\n3) Medium\n4) Difficult\n5) Evil\n\n--> ")
- if numClues_input.lower() in ["1", "1)", "one", "eins", "i", "extremely easy"]:
- numClues = random.randint(47,80)
- break
- elif numClues_input.lower() in ["2", "2)", "two", "zwei", "ii", "easy"]:
- numClues = random.randint(36,46)
- break
- elif numClues_input.lower() in ["3", "3)", "three", "drei", "iii", "medium"]:
- numClues = random.randint(32,35)
- break
- elif numClues_input.lower() in ["4", "4)", "four", "vier", "iv", "difficult"]:
- numClues = random.randint(28,31)
- break
- elif numClues_input.lower() in ["5", "5)", "five", "fünf", "v", "evil"]:
- numClues = random.randint(17,27)
- break
- print("\nSelect difficulty level...\n")
- print(f"\nYou have selected difficulty level {numClues_input}. Therefore you will get {numClues} clues.")
- numRemoveClues = 81-numClues
- ## remove up to 81-17=64 clues until there is a unique solution
- allCoordinates = list(itertools.product(range(0,9), repeat=2))
- while_counter = 0
- start = time.time()
- while True:
- removeCoordinates = random.choices(allCoordinates, k=numRemoveClues)
- for coord in removeCoordinates:
- row = coord[0]
- col = coord[1]
- sudoku[row, col] = 0
- counter = 0
- sudoku = solveSudoku(board=first_sudoku, random_nums=True, onlyFirstSolution=False, suppress_print=True)
- if counter == 1:
- return sudoku
- while_counter += 1
- if while_counter in [10,100,1000,10000,100000,1000000]:
- print(f"{while_counter} Sudokus with {numClues} clues have been found so far, but none of them is unique...")
- stop = time.time()
- elapsed_time = stop-start
- if elapsed_time > 120:
- print("Time elapsed has exceed the maximum waiting time of 120s.")
- break
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement