#### minesweeper.py

 ```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64``` ```import re from itertools import product # Top or bottom border, e.g. "+------+" HORIZONTAL_BORDER = re.compile(r''' \+ # starts with + \-+ # any number of - \+ # ends with + ''', re.VERBOSE) # Tile row, e.g. | * | TILE_ROW = re.compile(r''' \| # starts with | (\ |\*)+ # any number of ' ' or '*' \| # ends with | ''', re.VERBOSE) def surrounding_tiles(row, col): """ Generate coordinates of all tiles surrounding (row, col), excluding the tile itself """ return ( (row+i, col+j) for (i, j) in product((1, 0, -1), repeat=2) if i or j # exclude (0, 0) which is itself ) def board(inp): if not all(len(row) == len(inp[0]) for row in inp): raise ValueError("Rows must be of equal length") if not all(( HORIZONTAL_BORDER.match(inp[0]), HORIZONTAL_BORDER.match(inp[-1]), all(TILE_ROW.match(row) for row in inp[1:-1]) )): raise ValueError("Invalid board format") # Create a mutable structure that can be modified as we count mines tiles = [list(row) for row in inp] # Just iterate over the inner board - # the edges are handy for keeping indexes valid :) row_range = range(1, len(tiles)-1) col_range = range(1, len(tiles[0])-1) def increment_tile(row, col): value = tiles[row][col] if value == ' ': tiles[row][col] = '1' elif value.isdigit(): tiles[row][col] = str(int(value)+1) # Find mines and increment surrounding tiles for row in row_range: for col in col_range: if tiles[row][col] == '*': for (r, c) in surrounding_tiles(row, col): increment_tile(r, c) return [''.join(row) for row in tiles] ```