class Sudoku:
    def __init__(self, puzzle):
        self.puzzle = puzzle

    def print(self):
        for i, row in enumerate(self.puzzle):
            cells = [' %s ' % c if c else ' . ' for c in row]
            print('|'.join([''.join(cells[j:j + 3]) for j in (0, 3, 6)]))
            if i in (2, 5):
                print('---------+---------+---------')

    def solve(self):
        def find_free():
            for i in range(9):
                for j in range(9):
                    if self.puzzle[i][j] == 0:
                        return (i, j)
            return None

        def unused(i, j):
            i_, j_ = i // 3 * 3, j // 3 * 3
            cells = {(i, k) for k in range(9)}
            cells |= {(k, j) for k in range(9)}
            cells |= {(i, j) for i in range(i_, i_ + 3)
                             for j in range(j_, j_ + 3)}

            return set(range(1, 10)) - {self.puzzle[i][j] for i, j in cells}
        
        class SolutionFound(Exception):
            pass

        def recursive_solve():
            cell = find_free()
            if not cell:
                raise SolutionFound
            i, j = cell
            for value in unused(i, j):
                self.puzzle[i][j] = value
                recursive_solve()
            self.puzzle[i][j] = 0

        try:
            recursive_solve()
        except SolutionFound: 
            pass

with open("sudoku.txt") as f:
    A = Sudoku([[int(x) for x in line.strip()] for line in f])

A.solve()
A.print()
