Skip to content

Commit a3af490

Browse files
author
Mauricio Klein
committed
Add solution for challenge #46
1 parent d1fa529 commit a3af490

File tree

6 files changed

+116
-0
lines changed

6 files changed

+116
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,4 @@
4545
- [x] [Challenge 43: Contiguous Subarray with Maximum Sum](challenge-43/)
4646
- [x] [Challenge 44: Find the k-th Largest Element in a List](challenge-44/)
4747
- [x] [Challenge 45: Occurrences of a number in a sorted array](challenge-45/)
48+
- [x] [Challenge 46: Sudoku solver](challenge-46/)

challenge-46/Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
test:
2+
python test_*.py
3+
4+
.PHONY: test

challenge-46/README.md

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Sudoku solver
2+
3+
## Description
4+
5+
Given a partially filled 9×9 2D array `grid[9][9]`, the goal is to assign digits (from 1 to 9) to the empty cells (denoted by the number `zero`) so that every row, column, and subgrid of size 3×3 contains exactly one instance of the digits from 1 to 9.
6+
7+
## Example
8+
```
9+
Input:
10+
[
11+
[3, 0, 6, 5, 0, 8, 4, 9, 0],
12+
[5, 2, 0, 0, 0, 0, 0, 0, 0],
13+
[0, 8, 7, 0, 0, 0, 0, 3, 1],
14+
[0, 0, 3, 0, 1, 0, 0, 8, 0],
15+
[9, 0, 0, 8, 6, 3, 0, 0, 5],
16+
[0, 5, 0, 0, 9, 0, 6, 0, 0],
17+
[1, 3, 0, 0, 0, 0, 2, 5, 0],
18+
[0, 0, 0, 0, 0, 0, 0, 7, 4],
19+
[0, 0, 5, 2, 0, 6, 3, 0, 0]
20+
]
21+
22+
Output: a valid Sudoku board
23+
```

challenge-46/__init__.py

Whitespace-only changes.

challenge-46/solver.py

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
def sudoku(board, rows, columns):
2+
return helper(board, 0, 0, columns, rows)
3+
4+
def helper(board, r, c, rows, columns):
5+
def inbound(r, c):
6+
return (0 <= r < rows) and (0 <= c < columns)
7+
8+
# Out of bounds:
9+
# We filled all blank cells and, thus, a valid solution
10+
if not inbound(r, c):
11+
return True
12+
13+
nr, nc = next_pos(r, c, rows, columns)
14+
15+
if board[r][c] != 0:
16+
# This is a pre-filled cell, so skip
17+
# for the next one
18+
return helper(board, nr, nc, rows, columns)
19+
20+
for i in range(1, 10):
21+
if valid_placement(board, r, c, rows, columns, i):
22+
# "i" can be place in the cell without breaking
23+
# the sudoku rules. So, it's a canditate for solution.
24+
# Mark the cell with the value and try to solve
25+
# recursively for the remaining blank cells
26+
board[r][c] = i
27+
28+
if helper(board, nr, nc, rows, columns):
29+
return True
30+
else:
31+
# No solution found for the search branch:
32+
# reset the cell for the future attemps
33+
board[r][c] = 0
34+
35+
return False
36+
37+
def next_pos(r, c, rows, columns):
38+
if c + 1 == columns:
39+
return (r + 1, 0)
40+
else:
41+
return (r, c + 1)
42+
43+
def valid_placement(board, r, c, rows, columns, v):
44+
# Check conflict with row
45+
if v in board[r]:
46+
return False
47+
48+
# Check conflict with column
49+
for i in range(0, rows):
50+
if v == board[i][c]:
51+
return False
52+
53+
# Check conflict with the subgrid
54+
row_offset = r - r % 3
55+
col_offset = c - c % 3
56+
57+
for i in range(3):
58+
for j in range(3):
59+
if board[i + row_offset][j + col_offset] == v:
60+
return False
61+
62+
return True

challenge-46/test_solver.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import unittest, pprint
2+
from solver import sudoku
3+
4+
class TestSolver(unittest.TestCase):
5+
def test_sudoku(self):
6+
pp = pprint.PrettyPrinter(indent=4)
7+
8+
board = [
9+
[3, 0, 6, 5, 0, 8, 4, 9, 0],
10+
[5, 2, 0, 0, 0, 0, 0, 0, 0],
11+
[0, 8, 7, 0, 0, 0, 0, 3, 1],
12+
[0, 0, 3, 0, 1, 0, 0, 8, 0],
13+
[9, 0, 0, 8, 6, 3, 0, 0, 5],
14+
[0, 5, 0, 0, 9, 0, 6, 0, 0],
15+
[1, 3, 0, 0, 0, 0, 2, 5, 0],
16+
[0, 0, 0, 0, 0, 0, 0, 7, 4],
17+
[0, 0, 5, 2, 0, 6, 3, 0, 0]
18+
]
19+
20+
solved = sudoku(board, 9, 9)
21+
22+
pp.pprint(board)
23+
self.assertTrue(solved)
24+
25+
if __name__ == "__main__":
26+
unittest.main()

0 commit comments

Comments
 (0)