def solve_4347f46a(x):
    """
        This task consists of multiple coloured shapes in a grid that need to have their centres hollowed out,
         leaving only the boundaries of the shapes coloured.

        A convolution approach is used to implement this transformation.
        A 3x3 kernel with all values=1 and stride=1 is used iteratively across the input grid, performing a convolution
         with corresponding cells in the input grid that fall in the bounds of the kernel.
        The kernel starts in the top left corner and finishes in the bottom right corner of the input grid.
        Anytime the convolution results in a maximum value of colour*9, this means that all neighbours in all directions
         of a cell in the input grid are also coloured cells and therefore the cell in the input grid indexed by the centre
         of the kernel is inside a coloured shape. The corresponding cell in the output grid is overwritten with 0 as a result.

        Status: all training and test grids are solved correctly.

        Comments: - this algorithm turned out to be very efficient as it could transform on the fly by scanning the input grid
                     row by row, only needing one loop over the input.
                  - indexing in both the row and column directions was needed, resulting in nested for loops.
                  - convolution is a very applicable approach as it is commonly used in computer vision tasks.
                  - algorithm assumes no shapes have boundaries touching the extremities of the input grid.
    """
    yhat = x.copy() # return yhat after transformation is complete
    for i in range(1, x.shape[0]-1): # loop through rows in x, i is the x_coordinate of the centre of the 3x3 kernel over the image
        for j in range(1, x.shape[1]-1): # loop through columns of each row, j is the y_coordinate of the centre of the 3x3 kernel over the image
            if x[i][j] != 0: # centre of kernel is over a coloured cell of x
                # convolve the 3x3 kernel with the 3x3 portion of x inside the kernel boundaries
                colour = x[i][j]
                conv_res =   x[i-1][j-1] + x[i-1][j] + x[i-1][j+1] \
                           + x[i][j-1]   + x[i][j]   + x[i][j+1] \
                           + x[i+1][j-1] + x[i][j]   + x[i][j+1]
                if conv_res == colour*9: # maximum convolution result is when all cells in x under kernel are coloured
                    # the centre of kernel is over a coloured cell in x that IS INSIDE the boundaries of a coloured shape
                    yhat[i][j] = 0 # change cell inside shape to black in the output grid
    return yhat