def find_energy_minimum(self, energy, x, maxSteps=40000):
        r"""
        Naive hill descend algorithm:
        Starts at $y=0$ and iteratively chooses the direction of steepest descent from 
        a neighbourhood of the current position. If not indicated otherwise the neighbourhood
        consists of elements at Hamming distance less than or equal to $1$. 
        """
        E = energy
        y = np.zeros(self.output_size) 

        min_so_far = E(x, y)

        for _ in range(maxSteps):
            neighbours       = self.get_neighbours(y)
            energies         = np.array([ E(x,z) for z in neighbours ])
            steepest_descent = np.argmin(energies)

            if energies[steepest_descent] < min_so_far:
                y          = neighbours[steepest_descent]
                min_so_far =   energies[steepest_descent]
            else:
                break

        return y
r"""
        Naive hill descend algorithm:
        Starts at $y=0$ and iteratively chooses the direction of steepest descent from 
        a neighbourhood of the current position. If not indicated otherwise the neighbourhood
        consists of elements at Hamming distance less than or equal to $1$.