1
Fork 0
mirror of https://git.cs.ou.nl/joshua.moerman/puzzels.git synced 2025-05-13 16:27:44 +02:00
puzzels/sudoku-v1.py
Joshua Moerman c643b1baae typo
2024-03-15 12:16:25 +01:00

107 lines
2.4 KiB
Python

# (Dit was de orginele versie die ik maakte voor een kennisclip bij de OU.)
# Voor dit python programm moet je een python pakket installeren. De wegpagine
# is https://pysathq.github.io. Je kunt dit pakket installeren met pip.
# Voer hiervoor het volgende commando uit in een terminal:
#
# pip install python-sat
#
# Daarna kun je het programma gebruiken:
#
# python3 sudoku-v1.py
#
from pysat.solvers import Glucose3
next_var = 1
var_dict = {}
# x_r,c,d -> x_i
def var(r, c, d):
global next_var, var_dict
var_name = (r, c, d)
if var_name not in var_dict:
var_dict[var_name] = next_var
next_var = next_var + 1
return var_dict[var_name]
solver = Glucose3()
def unique(lits):
solver.add_clause(lits)
for (i, l1) in enumerate(lits):
for l2 in lits[i+1:]:
solver.add_clause([-l1, -l2])
# **********
# SPELREGELS
# **********
# 0: in elk hokje precies 1 cijfer
for row in range(9):
for column in range(9):
unique([var(row, column, digit) for digit in range(1, 10)])
# 1. in elke rij staat elk cijfer precies 1 keer
for row in range(9):
for digit in range(1, 10):
unique([var(row, column, digit) for column in range(9)])
# 2. in elke kolom staat elk cijfer precies 1 keer
for column in range(9):
for digit in range(1, 10):
unique([var(row, column, digit) for row in range(9)])
# 3. in elk blok staat elk cijfer precies 1 keer
block_ranges = [range(0,3), range(3,6), range(6,9)]
for row_block in block_ranges:
for column_block in block_ranges:
for digit in range(1, 10):
unique([var(row, column, digit) for row in row_block for column in column_block])
# ****************
# GEGEVEN GETALLEN
# ****************
# De drietallen staan voor (rij, kolom, getal)
known = [(0,3,7), (1,0,1), (2,3,4), (2,4,3), (2,6,2),
(3,8,6), (4,3,5), (4,5,9), (5,6,4), (5,7,1), (5,8,8),
(6,4,8), (6,5,1), (7,2,2), (7,7,5), (8,1,4), (8,6,3)
]
for (r, c, d) in known:
solver.add_clause([var(r, c, d)])
# ********
# OPLOSSEN
# ********
num_sols = 0
for m in solver.enum_models():
model = {}
for l in m:
if l < 0:
model[-l] = False
else:
model[l] = True
for row in range(9):
if row % 3 == 0:
print("")
for column in range(9):
if column % 3 == 0:
print(" ", end="")
for digit in range(1, 10):
if model[var(row, column, digit)]:
print(digit, end="")
print("")
print("")
num_sols = num_sols + 1
print("Aantal oplossingen:")
print(num_sols)