HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

OOP Sudoku solver with minimal guessing

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
withguessingminimalsolversudokuoop

Problem

Having only had experience with programming in Matlab I started this project to learn a real programing language, object-oriented programming and a proper coding style.

I wanted to implement a numerical version of how I would solve a sudoku and stay away from the plenty of solutions using backtracking (as much as possible). For clearness and (re)usability I wanted to create a class for this.

I hope that the actual code is clear enough so it doesn't need additional explanation. For the review I'm primarily concerned about the coding style and oop. Performance and algorithm choice is not really a concern at this point as the code runs at reasonable speed for me.

```
#!/usr/bin/env python3
# -- coding: utf-8 --
import numpy as np

class Sudoku():
"""Class for handling 9x9 sudokus.

Args:
input_grid (str): String with the path to a 9 line text
file with 9 numbers where gaps are
represented by '0'
input grid (nda): 9 by 9 numpy array with gaps set as '0'

Attributes:
grid (nda): current state of the sudoku grid
length (int): length of the grid, for now always 9
sub_length (int): sqrt of the length
check_sum (int): sum of a unique row/column
bu_grid (lst): list of backup grids used for guessing
guesses (int): number of guesses for the current grid
max_guesses (int): maximal number of guesses for the current grid
mask (nda): 9x9x9 numpy array (bit mask).

Example:
s = Sudoku(np.array(
[[5, 3, 0, 0, 7, 0, 0, 0, 0],
[6, 0, 0, 1, 9, 5, 0, 0, 0],
[0, 9, 8, 0, 0, 0, 0, 6, 0],
[8, 0, 0, 0, 6, 0, 0, 0, 3],
[4, 0, 0, 8, 0, 3, 0, 0, 1],
[7, 0, 0, 0, 2, 0, 0, 0, 6],
[0, 6, 0, 0, 0, 0, 2, 8, 0],
[0, 0, 0, 4, 1, 9, 0, 0, 5],
[0, 0, 0, 0, 8, 0, 0, 7, 9]]))
s.solve()
s.print_grid()
"""

def __init__(self, input_grid):

Solution

Overall, it looks pretty clean. I'm not super familiar with numpy, but it all looks pretty sane.

Some minor nits:

-
This:

with open(input_grid) as f:
    text = f.read()
    for line in text.split():
        grid.append([int(element) for element in line])


might be a little cleaner as:

with open(input_grid) as f:
    for line in f:
        grid.append([int(e) for e in line.split()])


-
In:

if not self.bu_grid:
    raise ValueError('No backup grid')
else:
    self.bu_grid[-1].guesses += 1
    bckup = self.bu_grid[-1]
    self.grid = bckup.grid
    self.guesses = bckup.guesses


you can get rid of the else: and dedent the rest of the block since the if block will raise and thus exit the routine that way.

Code Snippets

with open(input_grid) as f:
    text = f.read()
    for line in text.split():
        grid.append([int(element) for element in line])
with open(input_grid) as f:
    for line in f:
        grid.append([int(e) for e in line.split()])
if not self.bu_grid:
    raise ValueError('No backup grid')
else:
    self.bu_grid[-1].guesses += 1
    bckup = self.bu_grid[-1]
    self.grid = bckup.grid
    self.guesses = bckup.guesses

Context

StackExchange Code Review Q#156929, answer score: 3

Revisions (0)

No revisions yet.