### Sudoku Background

Sudoku is a game played on a 9x9 grid. The goal of the game is to fill all cells of the grid with digits from 1 to 9, so that each column, each row, and each of the nine 3x3 sub-grids (also known as blocks) contain all of the digits from 1 to 9. 
(More info at: http://en.wikipedia.org/wiki/Sudoku)

### Sudoku Solution Validator

Write a function `validSolution`/`ValidateSolution`/`valid_solution()` that accepts a 2D array representing a Sudoku board, and returns true if it is a valid solution, or false otherwise. The cells of the sudoku board may also contain 0's, which will represent empty cells. Boards containing one or more zeroes are considered to be invalid solutions.

The board is always 9 cells by 9 cells, and every cell only contains integers from 0 to 9.
 

### Examples

```
validSolution([
  [5, 3, 4, 6, 7, 8, 9, 1, 2],
  [6, 7, 2, 1, 9, 5, 3, 4, 8],
  [1, 9, 8, 3, 4, 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]
]); // => true
```

```
validSolution([
  [5, 3, 4, 6, 7, 8, 9, 1, 2], 
  [6, 7, 2, 1, 9, 0, 3, 4, 8],
  [1, 0, 0, 3, 4, 2, 5, 6, 0],
  [8, 5, 9, 7, 6, 1, 0, 2, 0],
  [4, 2, 6, 8, 5, 3, 7, 9, 1],
  [7, 1, 3, 9, 2, 4, 8, 5, 6],
  [9, 0, 1, 5, 3, 7, 2, 1, 4],
  [2, 8, 7, 4, 1, 9, 6, 3, 5],
  [3, 0, 0, 4, 8, 1, 1, 7, 9]
]); // => false
```

Difficulty: MEDIUM

Starter code:
def validSolution(board):
	

Solutions:
def validSolution(board):
	boxes = validate_boxes(board)
	cols = validate_cols(board)
	rows = validate_rows(board)
	return boxes and cols and rows

def validate_boxes(board):
	for i in range(0, 9, 3):
		for j in range(0, 9, 3):
			nums = board[i][j:j + 3] + board[i + 1][j:j + 3] + board[i + 2][j:j + 3]
			if not check_one_to_nine(nums):
				return False
	return True

def validate_cols(board):
	transposed = zip(*board)
	for row in transposed:
		if not check_one_to_nine(row):
			return False
	return True

def validate_rows(board):
	for row in board:
		if not check_one_to_nine(row):
			return False
	return True

def check_one_to_nine(lst):
	check = range(1, 10)
	return sorted(lst) == check


def validSolution(board):
	blocks = [[board[x + a][y + b] for a in (0, 1, 2) for b in (0, 1, 2)] for x in (0, 3, 6) for y in (0, 3, 6)]
	return not filter(lambda x: set(x) != set(range(1, 10)), board + zip(*board) + blocks)


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

def validSolution(board):
	for row in board:
		if sorted(row) != correct:
			return False
	for column in zip(*board):
		if sorted(column) != correct:
			return False
	for i in range(3):
		for j in range(3):
			region = []
			for line in board[i * 3:(i + 1) * 3]:
				region += line[j * 3:(j + 1) * 3]
			if sorted(region) != correct:
				return False
	return True


def valid_solution(m):
	is_valid = lambda a: len(a) == 9 and all([i + 1 in a for i in range(9)])
	get_block_as_row = lambda n: [m[3 * (n / 3) + i / 3][3 * n % 9 + i % 3] for i in range(9)]
	return all([is_valid(r) for r in m]) and all([is_valid([r[i] for r in m]) for i in range(9)]) and all([is_valid(get_block_as_row(i)) for i in range(9)])
validSolution = valid_solution


def get_row(board, row_index):
	return board[row_index]

def get_col(board, col_index):
	return [row[col_index] for row in board]

def get_subgrid(board, base_x, base_y):
	result = []
	for x in range(0, 3):
		for y in range(0, 3):
			result.append(board[base_x + x][base_y + y])
	return result

class InvalidSudokuSet(Exception):
	pass

def validate_9(arr, identifier='Group'):
	if len(arr) != 9:
		raise InvalidSudokuSet('{} has length {} (not 9): {}'.format(identifier, len(arr), arr))
	for number in range(1, 10):
		if number not in arr:
			raise InvalidSudokuSet("{} is missing '{}': {}".format(identifier, number, arr))

def validate_dimensions(board):
	if len(board) != 9:
		raise InvalidSudokuSet('Board contains {} rows:\n{}'.format(len(board), board))
	for row in board:
		if len(row) != 9:
			raise InvalidSudokuSet('Row does not have 9 columns:\n{}'.format(board))

def validate_rows(board):
	for index in range(0, 9):
		validate_9(get_row(board, index), 'Row')

def validate_columns(board):
	for index in range(0, 9):
		validate_9(get_col(board, index), 'Column')

def validate_subgrids(board):
	for x in range(0, 3):
		for y in range(0, 3):
			subgrid = get_subgrid(board, x * 3, y * 3)
			validate_9(subgrid, identifier='3x3 Subgrid')

def validSolution(board):
	try:
		validate_dimensions(board)
		validate_rows(board)
		validate_columns(board)
		validate_subgrids(board)
	except InvalidSudokuSet as e:
		print('Invalid board:\n{}\n'.format(board))
		print(e)
		return False
	print('Valid board:\n{}'.format(board))
	return True


from itertools import product

def validSolution(board):
	rows = board
	columns = list(map(list, list(zip(*board))))
	blocks = [[board[i][j] for (i, j) in product(range(x, x + 3), range(y, y + 3))] for (x, y) in product((0, 3, 6), repeat=2)]
	return all((sorted(line) == list(range(1, 10)) for lines in (rows, columns, blocks) for line in lines))


import numpy as np
from itertools import chain
nums = set(range(1, 10))

def validSolution(board):
	a = np.array(board)
	r = range(0, 9, 3)
	return all((set(v.flatten()) == nums for v in chain(a, a.T, (a[i:i + 3, j:j + 3] for i in r for j in r))))


def validSolution(board):
	valid = set(range(1, 10))
	for row in board:
		if set(row) != valid:
			return False
	for col in [[row[i] for row in board] for i in range(9)]:
		if set(col) != valid:
			return False
	for x in range(3):
		for y in range(3):
			if set(sum([row[x * 3:(x + 1) * 3] for row in board[y * 3:(y + 1) * 3]], [])) != valid:
				return False
	return True


def validSolution(board):
	for x in range(9):
		arr = [board[y][x] for y in range(9)]
		arr2 = [board[x][y] for y in range(9)]
		arr3 = [board[i][y] for y in range(x % 3 * 3, x % 3 * 3 + 3) for i in range(int(x / 3) * 3, int(x / 3) * 3 + 3)]
		for i in range(9):
			if arr[i] in arr[i + 1:]:
				return False
			if arr2[i] in arr2[i + 1:]:
				return False
			if arr3[i] in arr3[i + 1:]:
				return False
	return True


from itertools import chain

def validSolution(board):
	cols = zip(*board)
	squares = (chain(*(board[y + i][x:x + 3] for i in range(3))) for x in (0, 3, 6) for y in (0, 3, 6))
	good_range = set(range(1, 10))
	return all((set(zone) == good_range for zone in chain(board, cols, squares)))