It is necessary to read the sudoku from a file, write it into a matrix and decide recursion. How to compose recursion correctly? In the current version it works incorrect
def read_sudoku(filename): """ Прочитать Судоку из указанного файла """ digits = [c for c in open(filename).read() if c in '123456789.'] grid = group(digits, 9) return grid def display(values): """Вывод Судоку """ width = 2 line = '+'.join(['-' * (width * 3)] * 3) for row in range(9): print(''.join(values[row][col].center(width) + ('|' if str(col) in '25' else '') for col in range(9))) if str(row) in '25': print(line) print() def group(values, n): list1 = [] list2 = [] j = 0 for i in values: if j < n: list2.append(i) j += 1 if j == n: j = 0 list1.append(list2) list2 = [] return list1 def get_row(values, pos): row, col = pos i = 0 list = [] for j in values: if i == row: list = j i += 1 return list def get_col(values, pos): row, col = pos list = [] for j in values: for i in range(len(j)): if i == col: list.append(j[i]) return list def get_block(values, pos): """ Возвращает все значения из квадрата, в который попадает позиция pos """ row, col = pos i = 0 j = 0 list = [] borderRow1 = 0 borderRow2 = 0 borderCol1 = 0 borderCol2 = 0 if (row <= 2) and (row >= 0): borderRow1 = 0 borderRow2 = 2 elif (row <= 5) and (row >= 3): borderRow1 = 3 borderRow2 = 5 else: borderRow1 = 6 borderRow2 = 8 if (col <= 2) and (col >= 0): borderCol1 = 0 borderCol2 = 2 elif (col <= 5) and (col >= 3): borderCol1 = 3 borderCol2 = 5 else: borderCol1 = 6 borderCol2 = 8 while i <= 8: while j <= 8: if (i >= borderRow1) and (i <= borderRow2) and (j >= borderCol1) and (j <= borderCol2): list.append(values[i][j]) j += 1 j = 0 i += 1 return list def find_empty_positions(grid): row = 0 col = 0 t = True for i in grid: if t: for y in i: if y == '.': t = False break col += 1 if t: col = 0 row += 1 else: break if t: return None else: return (row, col) def find_possible_values(grid, pos): """ Вернуть все возможные значения для указанной позиции """ answer = ['1', '2', '3', '4', '5', '6', '7', '8', '9'] list1 = get_row(grid, pos) for i in list1: for j in answer: if i == j: answer.remove(j) list2 = get_col(grid, pos) for i in list2: for j in answer: if i == j: answer.remove(j) list3 = get_block(grid, pos) for i in list3: for j in answer: if i == j: answer.remove(j) return answer def solve(grid): """ Решение пазла, заданного в grid """ """ Как решать Судоку? 1. Найти свободную позицию 2. Найти все возможные значения, которые могут находиться на этой позиции 3. Для каждого возможного значения: 3.1. Поместить это значение на эту позицию 3.2. Продолжить решать оставшуюся часть пазла """ def answer(values): print('answer') setka = [] t = find_empty_positions(values) print(t) if t != None: row, col = t e = find_possible_values(values, t) print('Possible values') print(e) setka = values if len(e) > 0: for i in e: setka[row][col] = i display(setka) if check_solution(setka): return setka else: answer(setka) true_answer = answer(grid) def check_solution(solution): """ Если решение solution верно, то вернуть True, в противном случае False """ list1 = [0]*9 t = True for i in solution: if t: for j in i: if j == '.' : t = False break else: list1[int(j) - 1] += 1 if list1[int(j)-1] > 9: t = False break else: break if t: return True else: return False if __name__ == '__main__': for fname in ['puzzle1.txt', 'puzzle2.txt', 'puzzle3.txt']: grid = read_sudoku(fname) display(grid) solution = solve(grid) display(solution) print()