Skip to content

Commit 53ae9aa

Browse files
Fix simple coloring component handling
1 parent 1255cf5 commit 53ae9aa

File tree

2 files changed

+20
-9
lines changed

2 files changed

+20
-9
lines changed

src/sudoku_dlx/strategies.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -537,17 +537,22 @@ def add_links(cells: List[Tuple[int, int]]) -> None:
537537
add_links(_unit_cells_box(b))
538538

539539
color: List[Optional[int]] = [None] * len(nodes)
540+
component: List[Optional[int]] = [None] * len(nodes)
541+
comp_id = 0
540542
for start in range(len(nodes)):
541543
if color[start] is not None:
542544
continue
543545
color[start] = 0
546+
component[start] = comp_id
544547
stack = [start]
545548
while stack:
546549
u = stack.pop()
547550
for v in adj[u]:
548551
if color[v] is None:
549552
color[v] = 1 - color[u]
553+
component[v] = comp_id
550554
stack.append(v)
555+
comp_id += 1
551556

552557
for unit_kind in ("row", "col", "box"):
553558
for unit_idx in range(9):
@@ -558,13 +563,15 @@ def add_links(cells: List[Tuple[int, int]]) -> None:
558563
]
559564
if len(cells) < 2:
560565
continue
561-
by_color: Dict[int, List[Tuple[int, int]]] = {}
566+
by_color: Dict[Tuple[int, int], List[Tuple[int, int]]] = {}
562567
for (r, c) in cells:
563-
col = color[idx[(r, c)]]
564-
if col is None:
568+
node_idx = idx[(r, c)]
569+
col = color[node_idx]
570+
comp = component[node_idx]
571+
if col is None or comp is None:
565572
continue
566-
by_color.setdefault(col, []).append((r, c))
567-
for col_value, positions in sorted(by_color.items()):
573+
by_color.setdefault((comp, col), []).append((r, c))
574+
for (comp, col_value), positions in sorted(by_color.items()):
568575
if len(positions) >= 2:
569576
r, c = positions[0]
570577
if d in cand[r][c]:
@@ -575,6 +582,7 @@ def add_links(cells: List[Tuple[int, int]]) -> None:
575582
"digit": d,
576583
"unit": unit_kind,
577584
"unit_index": unit_idx,
585+
"component": comp,
578586
"color": col_value,
579587
"r": r,
580588
"c": c,

tests/test_strategies_extras.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,17 @@ def test_simple_coloring_one_elimination() -> None:
2424
grid = [[0] * 9 for _ in range(9)]
2525
cand = candidates(grid)
2626
digit = 9
27-
for r in range(2):
27+
# Limit digit to four cells in box 0 forming a 2x2 square. Rows and columns
28+
# now contain conjugate links for the digit, so simple coloring Rule 2
29+
# should identify a conflict inside the box and eliminate one candidate.
30+
for r in range(9):
2831
for c in range(9):
2932
cand[r][c].discard(digit)
30-
cand[r][0].add(digit)
31-
cand[r][3].add(digit)
32-
cand[2][0].add(digit)
33+
for r, c in [(0, 0), (0, 1), (1, 0), (1, 1)]:
34+
cand[r][c].add(digit)
3335

3436
move = apply_simple_coloring(grid, cand)
3537
assert move is not None
3638
assert move["strategy"] == "simple_coloring"
39+
assert move["digit"] == digit
3740
assert digit not in cand[move["r"]][move["c"]]

0 commit comments

Comments
 (0)