from utilities import * sudoku1 = ["5", "3", ".", ".", "7", ".", ".", ".", ".", "6", ".", ".", "1", "9", "5", ".", ".", ".", ".", "9", "8", ".", ".", ".", ".", "6", ".", "8", ".", ".", ".", "6", ".", ".", ".", "3", "4", ".", ".", "8", ".", "3", ".", ".", "1", "7", ".", ".", ".", "2", ".", ".", ".", "6", ".", "6", ".", ".", ".", ".", "2", "8", ".", ".", ".", ".", "4", "1", "9", ".", ".", "5", ".", ".", ".", ".", "8", ".", ".", "7", "9"] """ General note: we have decided to represent a sudoku board as a list of 81 values. Each value is a character, that can be a digit from 1 to 9, or a dot (".") to signify a blank spot. The values are listed in left-to-right, top-to-bottom order. It is our responsibility, in the rest of the code, to respect this representation decision. At the same time, it is good programming practice to make the rest of the code as independent of this decision as possible. A good programming guideline is that, if at any point we decide to change the representation, only a few changes should be necessary in the rest of the code. In order to ensure that our code as independent of the representation choice as possible, we will ensure that the ONLY functions that depend on this decision are the following functions: - check_sudoku_validity(sudoku) - compute_sudoku_position(row, col) - get_sudoku_value(sudoku, row, col) - set_sudoku_value(sudoku, row, col, value) - legal_sudoku_value - create_empty_sudoku - sudoku_deep_copy Furthermore, the rest of the code, when dealing with a sudoku, is only allowed to use the above functions to read information from a sudoku, or write information to a sudoku. """ """ input: a python object (can be anything, int, float, list, string...) output: True if the python object is a valid sudoku board, that follows our convention on how a sudoku board can be represented. """ def check_sudoku_validity(sudoku): if not(type(sudoku) is list): return False if len(sudoku) != 81: return False for entry in sudoku: if not(entry in "123456789."): return False return True """ inputs: row, col specify positions on a sudoku board. legal values for row and col are integers from 1 to 9 output: the position on the sudoku board (which is represented as a list) that stores the value for that row and col """ def compute_sudoku_position(row, col): position = (row-1)*9 + col-1 return position """ inputs: sudoku board, row and col output: the value stored in the sudoku board, for that row and col. Rows and columns are numbered from 1 to 9. """ def get_sudoku_value(sudoku, row, col): position = compute_sudoku_position(row, col) result = sudoku[position] return result """ inputs: a sudoku board output: a new sudoku board, that is a deep copy of the input (so that changing the output sudoku will have no effect on the input sudoku) """ def sudoku_deep_copy(in_sudoku): out_sudoku = in_sudoku[:] return out_sudoku """ inputs: sudoku board, row, col, value output: a new sudoku board, that is the same as the original sudoku board, except that the new board contains the specified value at the position specified by row and col """ def set_sudoku_value(in_sudoku, row, col, value): out_sudoku = sudoku_deep_copy(in_sudoku) position = compute_sudoku_position(row, col) out_sudoku[position] = value return out_sudoku """ create_empty_sudoku takes no input, and returns an empty sudoku board. """ def create_empty_sudoku(): sudoku_string = '.' * 81 result = list(sudoku_string) return result def legal_sudoku_value(value): if value in "123456789.": return True else: return False """ NOTE: All functions after this point should be independent of the specific sudoku representation """ """ This function prints a sudoku board. """ def print_sudoku(sudoku): string_version = sudoku_to_string(sudoku) print string_version """ This function converts a sudoku board into a string. This string can later be used for printing, or for saving to a file. The goal is that this string should be easy to read when printed. """ def sudoku_to_string(sudoku): result = "" for row in range(1, 10): result = result + get_sudoku_value(sudoku, row, 1) result = result + get_sudoku_value(sudoku, row, 2) result = result + get_sudoku_value(sudoku, row, 3) result = result + " " result = result + get_sudoku_value(sudoku, row, 4) result = result + get_sudoku_value(sudoku, row, 5) result = result + get_sudoku_value(sudoku, row, 6) result = result + " " result = result + get_sudoku_value(sudoku, row, 7) result = result + get_sudoku_value(sudoku, row, 8) result = result + get_sudoku_value(sudoku, row, 9) result = result + "\n" if (row == 3) or (row == 6): result = result + "\n" return result """ Saves a sudoku board into a file. """ def save_sudoku(sudoku, filename): fp = open(filename, "w") string_version = sudoku_to_string(sudoku) fp.write(string_version) fp.close() """ input: a sudoku board output: [row, col, value], a list of three items, specifying the row, column and value for the user's next move. """ def input_sudoku_move(): print "enter row, col, and value, on separate lines." while(True): row = input_integer("enter the row: ") if (row < 1) or (row > 9): print "The row must be between 1 and 9" else: break while(True): col = input_integer("enter the col: ") if (col < 1) or (col > 9): print "The col must be between 1 and 9" else: break while(True): value = raw_input("enter the value: ") if (legal_sudoku_value(value) == False): print value, "is not a legal sudoku value" else: break return [row, col, value] def make_move_interactively(in_sudoku): [row, col, value] = input_sudoku_move() out_sudoku = set_sudoku_value(in_sudoku, row, col, value) return out_sudoku """ We want a function that checks, at some specific position on the board, which numbers are legal values, using some simple rules """ def legal_position_numbers(sudoku, row, col): row_values = sudoku_row_values(sudoku, row) col_values = sudoku_col_values(sudoku, col) board_values = sudoku_board_values(sudoku, row, col) result = list("123456789") result = remove_values(result, row_values) result = remove_values(result, col_values) result = remove_values(result, board_values) return result