Skip to content

Instantly share code, notes, and snippets.

@AvinashKrSharma
Created August 21, 2017 18:05
Show Gist options
  • Save AvinashKrSharma/30f5e5571be4eb09c8de262bdc85ded5 to your computer and use it in GitHub Desktop.
Save AvinashKrSharma/30f5e5571be4eb09c8de262bdc85ded5 to your computer and use it in GitHub Desktop.
Small python3 script to check if a sudoku solution is valid or not
# Algorithm:
# 1. Get the length and sq_root of the grid size for e.g. for a 4x4 grid we are looking for values 4 and 2 respectively.
# 2. Loop for 0 to length and:
# Check if row is valid:
# To check this, push all values in row in an array and check if values have no duplicates and have no values
# outside possible range which is 1 to length
# Check if column is valid:
# To check this, push all values in column in an array and check if values have no duplicates and have no values
# outside possible range which is 1 to length
# 3. Loop from 0 to length - sq_root stepping root_size for every iteration:
# Check if subgrid is valid by checking each sq_root x sq_root grid for no duplicates and in range values
# 4. If all three of the above return True then grid is valid otherwise not.
# time complexity : O(n^2)
from math import sqrt
# a valid 4x4 grid
valid = [
[1, 4, 3, 2],
[3, 2, 4, 1],
[4, 1, 2, 3],
[2, 3, 1, 4]
]
# invalid coz grid has 9 in it which is invalid as it's out of range (1-4)
invalid_outofrange = [
[9, 4, 3, 2],
[3, 2, 4, 1],
[4, 1, 2, 3],
[2, 3, 1, 4]
]
# and invalid 9x9 grid
invalid = [
[5, 3, 4, 6, 7, 8, 9, 1, 2],
[6, 7, 2, 1, 9, 5, 3, 4, 8],
[1, 9, 8, 3, 8, 2, 5, 6, 7],
[8, 5, 9, 7, 6, 1, 4, 2, 3],
[4, 2, 6, 8, 5, 3, 7, 9, 1],
[7, 1, 3, 9, 2, 4, 8, 5, 6],
[9, 6, 1, 5, 3, 7, 2, 8, 4],
[2, 8, 7, 4, 1, 9, 6, 3, 5],
[3, 4, 5, 2, 8, 6, 1, 7, 9]
]
def has_no_duplicates(group):
# time complexity : O(n)
unique_digits = set()
for num in group:
if num != 0:
if num in unique_digits:
return False
unique_digits.add(num)
return True
def has_values_inside_range(group, size):
# time complexity : O(n)
start = 1
end = size
for i in range(0, size):
if group[i] < start or group[i] > end:
return False
return True
def is_row_valid(grid, row, size):
# time complexity : O(n) + O(n) = O(n)
group = []
for cell in grid[row]:
group.append(cell)
return has_no_duplicates(group) and has_values_inside_range(group, size)
def is_col_valid(grid, column, size):
# time complexity : O(n) + O(n) = O(n)
group = []
for row in grid:
group.append(row[column])
return has_no_duplicates(group) and has_values_inside_range(group, size)
def is_subgrid_valid(grid, row, column, root_size, size):
# time complexity : O(n) + O(n) = O(n)
group = []
for i in range(row, row + root_size):
for j in range(column, column + root_size):
group.append(grid[i][j])
return has_no_duplicates(group) and has_values_inside_range(group, size)
def isSudoku(grid):
# get length of grid (perfect square)
size = len(grid)
# square root of above length value for subgrids
root_size = int(sqrt(size))
# checking rows and columns for validity
for i in range(0, size):
if not is_row_valid(grid, i, size):
return False
if not is_col_valid(grid, i, size):
return False
# checking for subgrids validity
for i in range(0, size - root_size, root_size):
for j in range(0, size - root_size, root_size):
if not is_subgrid_valid(grid, i, j, root_size, size):
return False
# if we reach here then our grid is valid
return True
# should return :
# True
# False
# False
print(isSudoku(valid))
print(isSudoku(invalid_outofrange))
print(isSudoku(invalid))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment