Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions examples/crosswords/crosswords.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
MINLEN = 3


def main(puzzle, lines):
def solve(puzzle, lines):
puzzle = puzzle.rstrip().splitlines()
while puzzle and not puzzle[0]:
del puzzle[0]
Expand Down Expand Up @@ -60,10 +60,6 @@ def main(puzzle, lines):
del word[:]
col += 1

# hnames = ["h%d" % i for i in range(len(horizontal))]
# vnames = ["v%d" % i for i in range(len(vertical))]

# problem = Problem(MinConflictsSolver())
problem = Problem()

for hi, hword in enumerate(horizontal):
Expand Down Expand Up @@ -116,7 +112,7 @@ def main(puzzle, lines):

solution = problem.getSolution()
if not solution:
print("No solution found!")
return None, []

maxcol = 0
maxrow = 0
Expand Down Expand Up @@ -145,8 +141,16 @@ def main(puzzle, lines):
for (row, col), char in zip(word, solution[variable]):
matrix[row][col] = char

for row in range(maxrow + 1):
for col in range(maxcol + 1):
return solution, matrix


def main(puzzle, lines):
solution, matrix = solve(puzzle, lines)
if not solution:
print("No solution found!")
return
for row in range(len(matrix)):
for col in range(len(matrix[row])):
sys.stdout.write(matrix[row][col])
sys.stdout.write("\n")

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ select = [
convention = "google"

[tool.pytest.ini_options]
minversion = "9.1.1"
minversion = "8.0.0"
pythonpath = [
"constraint",
] # necessary to get coverage reports without installing with `-e`
Expand Down
64 changes: 64 additions & 0 deletions tests/test_examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""Tests for python-constraint example solvers."""

from examples.crosswords import crosswords
from examples.sudoku import sudoku
from examples.wordmath import seisseisdoze, sendmoremoney, twotwofour
from examples.xsum import xsum


def test_sudoku():
"""Verify that sudoku solver returns valid 9x9 solutions."""
solutions = sudoku.solve()
assert len(solutions) >= 1
sol = solutions[0]
assert sol[12] == 9
row1 = [sol[10 + col] for col in range(1, 10)]
assert sorted(row1) == list(range(1, 10))


def test_sendmoremoney():
"""Verify cryptarithmetic solution for SEND+MORE=MONEY."""
solutions = sendmoremoney.solve()
assert len(solutions) == 1
s = solutions[0]
assert s["s"] == 9 and s["e"] == 5 and s["m"] == 1 and s["y"] == 2


def test_twotwofour():
"""Verify cryptarithmetic solution for TWO+TWO=FOUR."""
solutions = twotwofour.solve()
assert len(solutions) > 0
for s in solutions:
two = s["t"] * 100 + s["w"] * 10 + s["o"]
four = s["f"] * 1000 + s["o"] * 100 + s["u"] * 10 + s["r"]
assert 2 * two == four


def test_seisseisdoze():
"""Verify cryptarithmetic solution for SEIS+SEIS=DOZE."""
solutions = seisseisdoze.solve()
assert len(solutions) > 0
for s in solutions:
seis = s["s"] * 1000 + s["e"] * 100 + s["i"] * 10 + s["s"]
doze = s["d"] * 1000 + s["o"] * 100 + s["z"] * 10 + s["e"]
assert 2 * seis == doze


def test_xsum():
"""Verify xsum solver where each 5-number row sums to 27."""
solutions = xsum.solve()
assert len(solutions) > 0
for s in solutions:
row1_sum = s["a"] + s["b"] + s["c"] + s["d"] + s["x"]
row2_sum = s["e"] + s["f"] + s["g"] + s["h"] + s["x"]
assert row1_sum == 27
assert row2_sum == 27


def test_crosswords():
"""Verify crossword puzzle solver execution with sample mask and word list."""
puzzle = "####\n####\n####\n####"
words = ["DATA", "CODE", "TEST", "MATH", "BYTE", "DISK", "FILE", "FLOW"]
solution, matrix = crosswords.solve(puzzle, words)
assert isinstance(matrix, list)