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

Backtracing Sudoku solver

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

Problem

I have made a backtracking Sudoku solver in Python but it's working quite slow.

Originally, It had been working on 4 by 4 grids, which worked fine.

But now, trying to solve 9 by 9 grids takes a very long time.

I haven't found out the exact reason but I feel that there is one major flaw that is making it so time consuming, However, I could not identify it.

I have seen similar programs and they seem faster.

The main class is Sudoku, however specifically the code which solves the Sudoku is in Sudoku.solve().

The Sudoku array is a NumPy array.

```
import numpy
def is_proper_sudoku(iterable):
count = {}
for val in iterable:
if val in count.keys():
count[val] += 1
else:
count[val] = 1
for var in count.keys():
if var != 0 and count[var] > 1:
return False
return True

# CLASSES
class Sudoku:
def __init__(self, size):
self.size = size #Size for future use

map_list = [[0 for val in range(size2)] for val in range(size2)]
self.map = numpy.array(map_list, numpy.int8) #Sudoku Body

self.empty = [(each_y, each_x) for each_y in range(size2) for each_x in range(size2)]

self.strides = self.map.itemsize * numpy.array([size4, size, size2, 1])

self.bulge_blocks = numpy.lib.stride_tricks.as_strided(self.map, (size, size, size, size), self.strides)
self.blocks = numpy.array([row.flatten() for row in self.bulge_blocks]).reshape(size, size, size**2) #Defining Blocks

def solve(self): #https://en.wikipedia.org/wiki/Sudoku_solving_algorithms

if not self.check_valid:
return False

y, x = 0, 0 #Setting the starting position.

done = False

global tried, changes

tried = [] #Stores the not working:(, , , ) #inserted_value or then_array
changes = [] #All Changes: Tuples: (, , )

while not done: #Looping

if self.map[y, x] == 0: #Making sure that the spac

Solution

Function calling bug

if not self.check_valid:
        return False


You omitted the parenthesis, this means you are talking about the value of the function object, that is always true. So this check is basically jumped.

The fix is:

if not self.check_valid():
        return False


Usage of built-ins : Counter and all

The definition of is_proper_sudoku that you use feels low-level as you re-invent the Counter and all built-ins:

def is_proper_sudoku(iterable):
    count = {}
    for val in iterable:
        if val in count.keys():
            count[val] += 1
        else:
            count[val] = 1
    for var in count.keys():
        if var != 0 and count[var] > 1:
            return False
    return True


You could write that as:

def is_proper_sudoku(iterable):
    count = collections.Counter(iterable)
    return all(not (var != 0 and count[var] > 1) for var in count.keys())

Code Snippets

if not self.check_valid:
        return False
if not self.check_valid():
        return False
def is_proper_sudoku(iterable):
    count = {}
    for val in iterable:
        if val in count.keys():
            count[val] += 1
        else:
            count[val] = 1
    for var in count.keys():
        if var != 0 and count[var] > 1:
            return False
    return True
def is_proper_sudoku(iterable):
    count = collections.Counter(iterable)
    return all(not (var != 0 and count[var] > 1) for var in count.keys())

Context

StackExchange Code Review Q#115170, answer score: 5

Revisions (0)

No revisions yet.