""" Starter code for a Sudoku solver, adapted from UMass CS 220. To run from the command line: python3 starter.py This will run the unit tests at the end of the file. """ import unittest class Board: """Board(board_dict) is a class that represents a Sudoku board, where: - board_dict is a dictionary from (row, col) to a list of available values. The rows and columns are integers in the range 0 .. 8 inclusive. Each available value is an integer in the range 1 .. 9 inclusive.""" def __init__(self, board_dict): """board_dict should be a dictionary, as described in the definition of the Board class.""" self.board_dict = board_dict def __str__(self): """Prints the board nicely, arranging board_dict like a Sudoku board.""" rows = [ ] for row in range(0, 9): col_strs = [ ] for col in range(0, 9): val_str = ''.join(str(x) for x in self.board_dict[(row, col)]) # Pad with spaces for alignment. val_str = val_str + (' ' * (9 - len(val_str))) col_strs.append(val_str) # Horizontal bar to separate boxes if col == 2 or col == 5: col_strs.append('|') rows.append(' '.join(col_strs)) # Vertical bar to separate boxes if row == 2 or row == 5: rows.append(93 * '-') return '\n'.join(rows) def copy(self): """Creates a deep copy of this board. Use this method to create a copy of the board before modifying the available values in any cell.""" new_dict = { } for (k, v) in self.board_dict.items(): new_dict[k] = v.copy() return Board(new_dict) def value_at(self, row, col): """Returns the value at the cell with the given row and column (zero indexed). Produces None if the cell has more than one available value.""" # TODO: Implement raise NotImplementedError("value_at") def place(self, row, col, value): """Places value at the given row and column. Eliminates value from the peers of (row, col) and recursively calls place on any cell that is constrained to exactly one value.""" # TODO: Implement raise NotImplementedError("place") def parse(sudoku_string): """Parses a string of 81 digits and periods for empty cells into, produce a Board that represents the Sudoku board.""" # TODO: Implement raise NotImplementedError("parse") def peers(row, col): """Returns the peers of the given row and column, as a list of tuples.""" # TODO: Implement raise NotImplementedError("peers") class SudokuTests(unittest.TestCase): def test_solved_puzzle(self): s = "853697421914238675762145893128563947475982136396471582581724369637859214249316758" board = parse(s) assert(board.value_at(0,0)==8) def test_solve_one(self): s = ".53697421914238675762145893128563947475982136396471582581724369637859214249316758" board = parse(s) assert(board.value_at(0,0)==8) def test_solve_third(self): s = "85.697421914238675762145893128563947475982136396471582581724369637859214249316758" board = parse(s) assert(board.value_at(0,2)==3) def test_empty_puzzle(self): s = "."*81 board = parse(s) board_dict = { } for i in range(9): for j in range(9): board_dict[(i, j)] = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] assert(board.board_dict == board_dict) if __name__ == "__main__": unittest.main()