Using google ortools - the following will either generate a dummy sudoku array or will solve a candidate. The code is probably more verbose than required, any feedback is appreciated.
The idea is to solve a constraint-programming problem that involves
In addition, when trying to solve existing sudoku, we add additional constraints on variables that already have assigned value.
from ortools.constraint_solver import pywrapcp
import numpy as np
def sudoku_solver(candidate = None):
solver = pywrapcp.Solver("Sudoku")
variables = [solver.IntVar(1,9,f"x{i}") for i in range(81)]
if len(candidate)>0:
candidate = np.int64(candidate)
for i in range(81):
val = candidate[i]
if val !=0:
solver.Add(variables[i] == int(val))
def set_constraints():
for i in range(9):
# All columns should be different
q=[variables[j] for j in list(range(i,81,9))]
solver.Add(solver.AllDifferent(q))
#All rows should be different
q2=[variables[j] for j in list(range(i*9,(i+1)*9))]
solver.Add(solver.AllDifferent(q2))
#All values in the sub-matrix should be different
a = list(range(81))
sub_blocks = a[3*i:3*(i+9):9] + a[3*i+1:3*(i+9)+1:9] + a[3*i+2:3*(i+9)+2:9]
q3 = [variables[j] for j in sub_blocks]
solver.Add(solver.AllDifferent(q3))
set_constraints()
db = solver.Phase(variables, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE)
solver.NewSearch(db)
results_store =[]
num_solutions =0
total_solutions = 5
while solver.NextSolution() and num_solutions<total_solutions:
results = [j.Value() for j in variables]
results_store.append(results)
num_solutions +=1
return results_store
candidate = np.array([0, 2, 0, 4, 5, 6, 0, 8, 0, 0, 5, 6, 7, 8, 9, 0, 0, 3, 7, 0, 9, 0,
2, 0, 4, 5, 6, 2, 0, 1, 5, 0, 4, 8, 9, 7, 5, 0, 4, 8, 0, 0, 0, 0,
0, 3, 1, 0, 6, 4, 5, 9, 7, 0, 0, 0, 5, 0, 7, 8, 3, 1, 2, 8, 0, 7,
0, 1, 0, 5, 0, 4, 9, 7, 8, 0, 3, 0, 0, 0, 5])
results_store = sudoku_solver(candidate)