### 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: interview

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):
    # check rows
    for row in board:
        if sorted(row) != correct:
            return False
    
    # check columns
    for column in zip(*board):
        if sorted(column) != correct:
            return False
    
    # check regions
    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
    
    # if everything correct
    return True

# PEP 8 - Function names should be in snake_case
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)])

# Just to pass the Kata
validSolution = valid_solution

# Accessors
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):
    # Returns elements (array) in a 3x3 subgrid
    # base_x,base_y are the x,y coordinates of the top-left element in the 3x3 subgrid
    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"):
    # Validates any 9 elements
    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))