code: 
  
  
  '''simple docstring'''
  
  
  
  import math
  
  
  
  
  
  class 							__UpperCamelCase       :
  
  
  
  
  	def __init__(     self		,       __a		,       __a		,       __a		,       __a							):
  
  						'''simple docstring'''
  
  
  
  
  
  						__a    : Union[str, Any]      					=						x
  						__a    : List[str]      					=						y
  						__a    : Union[str, Any]      					=						step_size
  						__a    : Tuple      					=						function_to_optimize
  
  
  
  
  	def    __UpperCAmelCase							(     self							):
  
  						'''simple docstring'''
  
  
  
  
  
  						return self.function(self.x		,       self.y							)
  
  
  
  
  	def    __UpperCAmelCase							(     self							):
  
  						'''simple docstring'''
  
  
  
  
  
  						__a    : Union[str, Any]      					=						self.step_size
  						return [
  						    SearchProblem(__a		,       __a		,       __a		,       self.function							)
  						    for x, y in (
  						        (self.x - step_size, self.y - step_size),
  						        (self.x - step_size, self.y),
  						        (self.x - step_size, self.y + step_size),
  						        (self.x, self.y - step_size),
  						        (self.x, self.y + step_size),
  						        (self.x + step_size, self.y - step_size),
  						        (self.x + step_size, self.y),
  						        (self.x + step_size, self.y + step_size),
  						    )
  						]
  
  
  
  
  	def __hash__(     self							):
  
  						'''simple docstring'''
  
  
  
  
  
  						return hash(str(self							)							)
  
  
  
  
  	def __eq__(     self		,       __a							):
  
  						'''simple docstring'''
  
  
  
  
  
  						if isinstance(__a		,       __a							):
  											return hash(str(self							)							) == hash(str(__a							)							)
  						return False
  
  
  
  
  
  	def __str__(     self							):
  
  						'''simple docstring'''
  
  
  
  
  
  						return f"""x: {self.x} y: {self.y}"""
  
  
  
  
  
  
  def 						lowerCamelCase							(_SCREAMING_SNAKE_CASE   :     Union[str, Any]		,   _SCREAMING_SNAKE_CASE   :     bool = True		,   _SCREAMING_SNAKE_CASE   :     float = math.inf		,   _SCREAMING_SNAKE_CASE   :     float = -math.inf		,   _SCREAMING_SNAKE_CASE   :     float = math.inf		,   _SCREAMING_SNAKE_CASE   :     float = -math.inf		,   _SCREAMING_SNAKE_CASE   :     bool = False		,   _SCREAMING_SNAKE_CASE   :     int = 10_000		,   ):
  					__a    : Optional[Any]      					=						search_prob
  					__a    : List[Any]      					=						[]  # list to store the current score at each iteration
  					__a    : Any      					=						0
  					__a    : int      					=						False
  					__a    : Tuple      					=						set()
  					while not solution_found and iterations < max_iter:
  										visited.add(_SCREAMING_SNAKE_CASE     )
  										iterations += 1
  										__a    : Optional[Any]      					=						current_state.score()
  										scores.append(_SCREAMING_SNAKE_CASE     )
  										__a    : List[Any]      					=						current_state.get_neighbors()
  										__a    : Optional[Any]      					=						-math.inf
  										__a    : str      					=						math.inf
  										__a    : str      					=						None  # to hold the next best neighbor
  										for neighbor in neighbors:
  															if neighbor in visited:
  																				continue  # do not want to visit the same state again
  															if (
  															    neighbor.x > max_x
  															    or neighbor.x < min_x
  															    or neighbor.y > max_y
  															    or neighbor.y < min_y
  															):
  																				continue  # neighbor outside our bounds
  															__a    : List[Any]      					=						neighbor.score() - current_score
  															if find_max:  # finding max
  																				# going to direction with greatest ascent
  																				if change > max_change and change > 0:
  																									__a    : Dict      					=						change
  																									__a    : str      					=						neighbor
  															else:  # finding min
  																				# to direction with greatest descent
  																				if change < min_change and change < 0:
  																									__a    : List[str]      					=						change
  																									__a    : Tuple      					=						neighbor
  										if next_state is not None:
  															# we found at least one neighbor which improved the current state
  															__a    : Tuple      					=						next_state
  										else:
  															# since we have no neighbor that improves the solution we stop the search
  															__a    : int      					=						True
  
  					if visualization:
  										from matplotlib import pyplot as plt
  
  										plt.plot(range(_SCREAMING_SNAKE_CASE     )		,   _SCREAMING_SNAKE_CASE     )
  										plt.xlabel('Iterations'     )
  										plt.ylabel('Function values'     )
  										plt.show()
  
  					return current_state
  
  
  if __name__ == "__main__":
  	import doctest
  
  	doctest.testmod()
  
  
  
  
  
  
  	def 						lowerCamelCase							(_SCREAMING_SNAKE_CASE   :     Union[str, Any]		,   _SCREAMING_SNAKE_CASE   :     Union[str, Any]     ):
  						return (x**2) + (y**2)
  
  	# starting the problem with initial coordinates (3, 4)
  	__lowercase			:		Dict =			SearchProblem(x=3, y=4, step_size=1, function_to_optimize=test_fa)
  	__lowercase			:		Tuple =			hill_climbing(prob, find_max=False)
  	print(
  	    'The minimum score for f(x, y) = x^2 + y^2 found via hill climbing: '
  	    f'''{local_min.score()}'''
  	)
  
  	# starting the problem with initial coordinates (12, 47)
  	__lowercase			:		Optional[Any] =			SearchProblem(x=12, y=47, step_size=1, function_to_optimize=test_fa)
  	__lowercase			:		Tuple =			hill_climbing(
  	    prob, find_max=False, max_x=1_00, min_x=5, max_y=50, min_y=-5, visualization=True
  	)
  	print(
  	    'The minimum score for f(x, y) = x^2 + y^2 with the domain 100 > x > 5 '
  	    f'''and 50 > y > - 5 found via hill climbing: {local_min.score()}'''
  	)
  
  
  
  
  
  
  	def 						lowerCamelCase							(_SCREAMING_SNAKE_CASE   :     Any		,   _SCREAMING_SNAKE_CASE   :     Optional[Any]     ):
  						return (3 * x**2) - (6 * y)
  
  	__lowercase			:		Optional[Any] =			SearchProblem(x=3, y=4, step_size=1, function_to_optimize=test_fa)
  	__lowercase			:		List[Any] =			hill_climbing(prob, find_max=True)
  
  
  
  
  	print(
  	    'The maximum score for f(x, y) = x^2 + y^2 found via hill climbing: '
  	    f'''{local_min.score()}'''
  	)
  
  
  
  
style_context: 
  
  
  '''simple docstring'''
  
  
  
  def 						lowerCamelCase							(_SCREAMING_SNAKE_CASE   :     set		,   _SCREAMING_SNAKE_CASE   :     set     ):
  					assert isinstance(_SCREAMING_SNAKE_CASE		,   _SCREAMING_SNAKE_CASE     ), F"""The input value of [set_a={set_a}] is not a set"""
  					assert isinstance(_SCREAMING_SNAKE_CASE		,   _SCREAMING_SNAKE_CASE     ), F"""The input value of [set_b={set_b}] is not a set"""
  
  					return {a + b for a in set_a for b in set_b}
  
  
  if __name__ == "__main__":
  	from doctest import testmod
  
  	testmod()
  
  
  
  