How can I decrease the time complexity and increase efficiency, without writing a new algorithm. My solution solves the majority of puzzles in a fast time, but for some difficult ones it can take over a minute! I have added some of the difficult puzzles below the code. ``` import numpy as np from skimage.util import view_as_blocks # pip install scikit-image #input: 9x9 numpy array, empty cell = 0 #output: 9x9 numpy array: if not solution all array entries should be -1 #backtracking depth-first search with constraint propagation #searches for 0 value in board def zero_search(sudoku): for i in range(len(sudoku)): for j in range(len(sudoku[0])): if sudoku[i][j] == 0: return (i, j) # row, col return False #parameters: board, num = inserted value, pos = board position(vector/tuple) def valid(sudoku, num, pos): # Check row for i in range(len(sudoku[0])): if sudoku[pos[0]][i] == num and pos[1] != i: return False # Check column for i in range(len(sudoku)): if sudoku[i][pos[1]] == num and pos[0] != i: return False # Check box box_x = pos[1] // 3 box_y = pos[0] // 3 #y-axis/columns for i in range(box_y*3, box_y*3 + 3): #x-axis/rows for j in range(box_x * 3, box_x*3 + 3): if sudoku[i][j] == num and (i,j) != pos: return False return True def solver(sudoku): find = zero_search(sudoku) if not find: return True else: row, col = find #check insertion values 1-9 for i in range(1,10): if valid(sudoku, i, (row, col)): sudoku[row][col] = i if solver(sudoku): return True sudoku[row][col] = 0 return False def initial_invalid(sudoku): # Check row for i in range(9): dup_lst=[] for j in range(9): if sudoku[j][i]!=0: if sudoku[j][i] in dup_lst: return True else: dup_lst.append(sudoku[j][i]) #check column for i in range(9): dup_lst=[] for j in range(9): if sudoku[i][j]!=0: if sudoku[i][j] in dup_lst: return True else: dup_lst.append(sudoku[i][j]) #not needed def final_valid (sudoku): subgrids = view_as_blocks(sudoku, (3, 3)) sums = [np.sum(subgrids[i][j]) for j in range(3) for i in range(3)] if sum(sums) !=405: return False else: return True #row_sum = sudoku.sum(axis=1) #if sum(row_sum) != 405: # return False #col_sum = sudoku.sum(axis=0) #if sum(col_sum) != 405: # return False def sudoku_solver(sudoku): if initial_invalid(sudoku): return np.full((9,9),-1) if solver(sudoku): return sudoku else: return np.full((9,9),-1) ``` ```python [[0 8 0 4 3 0 0 0 0] [0 0 5 0 0 9 0 0 0] [6 0 0 0 8 0 0 7 0] [0 0 0 0 9 0 0 0 3] [0 0 0 8 0 7 0 0 0] [9 0 0 0 0 0 0 5 4] [0 6 0 0 0 0 0 0 5] [0 0 8 0 0 0 4 0 0] [0 4 0 0 0 6 0 1 0]] [[0 0 2 0 0 0 0 0 4] [0 5 0 0 1 3 7 0 0] [7 9 0 0 0 0 0 5 0] [0 0 9 0 0 0 0 6 0] [0 0 0 0 3 0 5 0 8] [5 0 7 0 0 0 4 0 0] [0 0 0 0 6 0 8 0 0] [0 6 0 0 2 7 0 4 0] [8 0 0 0 0 0 0 2 0]] [[0 0 0 6 0 0 2 0 0] [0 0 0 0 0 9 0 6 0] [0 8 0 0 0 5 0 0 3] [1 0 0 4 0 0 9 0 0] [8 3 0 0 0 0 0 0 0] [0 2 0 0 0 6 0 0 0] [0 0 0 0 6 0 0 0 0] [2 5 0 3 0 7 0 9 0] [0 0 1 0 0 0 0 8 4]]