# Codewars

https://www.codewars.com/kata/validate-sudoku-with-size-nxn/python

Given a Sudoku data structure with size NxN, N > 0 and √N == integer, write a method to validate if it has been filled out correctly.

The data structure is a multi-dimensional Array(in Rust: Vec<Vec<u32>>) , ie:

[
[7,8,4,  1,5,9,  3,2,6],
[5,3,9,  6,7,2,  8,4,1],
[6,1,2,  4,3,8,  7,5,9],

[9,2,8,  7,1,5,  4,6,3],
[3,5,7,  8,4,6,  1,9,2],
[4,6,1,  9,2,3,  5,8,7],

[8,7,6,  3,9,4,  2,1,5],
[2,4,3,  5,6,1,  9,7,8],
[1,9,5,  2,8,7,  6,3,4]
]

Rules for validation

• Data structure dimension: NxN where N > 0 and √N == integer
• Rows may only contain integers: 1..N (N included)
• Columns may only contain integers: 1..N (N included)
• ‘Little squares’ (3x3 in example above) may also only contain integers: 1..N (N included)

# Martin’s comment

To be perfectly honest I have never played the sudoku. So firstly I had to learn a how to play it from Sudoku.com, and later solve the problem. My solution is definetely not the shortest nor ideal one but it works. I had saved a lot of work and issues using NumPy library in Python which I would like to learn more deeply.

Below is my solution.

# Martin’s solution

import numpy, math

class Sudoku(object):
def __init__(self, m):
self.matrix = numpy.matrix(m)
def is_valid(self):
self.mysum = sum(x for x in range(1,len(self.matrix)+1))
self.mylen = int(math.sqrt(len(self.matrix)))
# iterate over submatrixes
for x in range(0,self.mylen):
for y in range(0, self.mylen):
submatrix = self.matrix[x*self.mylen:x*self.mylen+self.mylen,y*self.mylen:y*self.mylen+self.mylen]
for i in range(1,self.mylen):
if i not in submatrix.A1.tolist():
return False
if numpy.sum(submatrix) != self.mysum:
return False
results = self.numpy_lines(1) + self.numpy_lines(0) # rows + columns parsing
for result in results:
if not result:
return False
return True

def line_sudoku(self, line):
line = line.tolist()[0]
if sum(line) != self.mysum:
return False
for i in range(1, self.mylen):
if i not in line:
return False
return True

def numpy_lines(self,axis):
return numpy.apply_along_axis(self.line_sudoku, axis = axis, arr = self.matrix).tolist()

goodSudoku = Sudoku([
[1,4, 2,3],
[3,2, 4,1],

[4,1, 3,2],
[2,3, 1,4]
])

print(goodSudoku.is_valid())

# Tests

# Valid Sudoku
goodSudoku1 = Sudoku([
[7,8,4, 1,5,9, 3,2,6],
[5,3,9, 6,7,2, 8,4,1],
[6,1,2, 4,3,8, 7,5,9],

[9,2,8, 7,1,5, 4,6,3],
[3,5,7, 8,4,6, 1,9,2],
[4,6,1, 9,2,3, 5,8,7],

[8,7,6, 3,9,4, 2,1,5],
[2,4,3, 5,6,1, 9,7,8],
[1,9,5, 2,8,7, 6,3,4]
])

goodSudoku2 = Sudoku([
[1,4, 2,3],
[3,2, 4,1],

[4,1, 3,2],
[2,3, 1,4]
])

# Invalid Sudoku
[0,2,3, 4,5,6, 7,8,9],
[1,2,3, 4,5,6, 7,8,9],
[1,2,3, 4,5,6, 7,8,9],

[1,2,3, 4,5,6, 7,8,9],
[1,2,3, 4,5,6, 7,8,9],
[1,2,3, 4,5,6, 7,8,9],

[1,2,3, 4,5,6, 7,8,9],
[1,2,3, 4,5,6, 7,8,9],
[1,2,3, 4,5,6, 7,8,9]
])