


"""simple docstring"""



from math import factorial







class _lowerCAmelCase       :







   def __init__(			self		,			UpperCamelCase__		,			UpperCamelCase__		)			->	Dict:

       '''simple docstring'''




       snake_case					:   Optional[Any]         =					real
       if isinstance(lowerCamelCase__		,			lowerCamelCase__		):
           snake_case					:   Any         =					[1] * rank
       else:
           snake_case					:   Dict         =					rank







   def __repr__(			self		)			->	List[str]:

       '''simple docstring'''




       return (
           F'{self.real}+'
           F'{"+".join(str(lowerCamelCase__		)+"E"+str(n+1		)for n,dual in enumerate(self.duals		)		)}'
       )







   def 				lowerCamelCase	(			self		)			->	Tuple:

       '''simple docstring'''




       snake_case					:   Union[str, Any]         =					self.duals.copy()
       while cur[-1] == 0:
           cur.pop(-1		)
       return Dual(self.real		,			lowerCamelCase__		)







   def __add__(			self		,			UpperCamelCase__		)			->	Any:

       '''simple docstring'''




       if not isinstance(lowerCamelCase__		,			lowerCamelCase__		):
           return Dual(self.real + other		,			self.duals		)
       snake_case					:   Optional[int]         =					self.duals.copy()
       snake_case					:   Optional[int]         =					other.duals.copy()
       if len(lowerCamelCase__		) > len(lowerCamelCase__		):
           o_dual.extend([1] * (len(lowerCamelCase__		) - len(lowerCamelCase__		))		)
       elif len(lowerCamelCase__		) < len(lowerCamelCase__		):
           s_dual.extend([1] * (len(lowerCamelCase__		) - len(lowerCamelCase__		))		)
       snake_case					:   Union[str, Any]         =					[]
       for i in range(len(lowerCamelCase__		)		):
           new_duals.append(s_dual[i] + o_dual[i]		)
       return Dual(self.real + other.real		,			lowerCamelCase__		)

   __UpperCAmelCase				: Tuple													=						__add__







   def __sub__(			self		,			UpperCamelCase__		)			->	Dict:

       '''simple docstring'''




       return self + other * -1







   def __mul__(			self		,			UpperCamelCase__		)			->	Union[str, Any]:

       '''simple docstring'''




       if not isinstance(lowerCamelCase__		,			lowerCamelCase__		):
           snake_case					:   Optional[int]         =					[]
           for i in self.duals:
               new_duals.append(i * other		)
           return Dual(self.real * other		,			lowerCamelCase__		)
       snake_case					:   Union[str, Any]         =					[0] * (len(self.duals		) + len(other.duals		) + 1)
       for i, item in enumerate(self.duals		):
           for j, jtem in enumerate(other.duals		):
               new_duals[i + j + 1] += item * jtem
       for k in range(len(self.duals		)		):
           new_duals[k] += self.duals[k] * other.real
       for index in range(len(other.duals		)		):
           new_duals[index] += other.duals[index] * self.real
       return Dual(self.real * other.real		,			lowerCamelCase__		)

   __UpperCAmelCase				: Union[str, Any]													=						__mul__







   def __truediv__(			self		,			UpperCamelCase__		)			->	Union[str, Any]:

       '''simple docstring'''




       if not isinstance(lowerCamelCase__		,			lowerCamelCase__		):
           snake_case					:   Union[str, Any]         =					[]
           for i in self.duals:
               new_duals.append(i / other		)
           return Dual(self.real / other		,			lowerCamelCase__		)
       raise ValueError







   def __floordiv__(			self		,			UpperCamelCase__		)			->	List[str]:

       '''simple docstring'''




       if not isinstance(lowerCamelCase__		,			lowerCamelCase__		):
           snake_case					:   Tuple         =					[]
           for i in self.duals:
               new_duals.append(i // other		)
           return Dual(self.real // other		,			lowerCamelCase__		)
       raise ValueError







   def __pow__(			self		,			UpperCamelCase__		)			->	Optional[int]:

       '''simple docstring'''




       if n < 0 or isinstance(lowerCamelCase__		,			lowerCamelCase__		):
           raise ValueError("power must be a positive integer"		)
       if n == 0:
           return 1
       if n == 1:
           return self
       snake_case					:   str         =					self
       for _ in range(n - 1		):
           x *= self
       return x







def 						__lowerCAmelCase		(		lowercase						:						Union[str, Any]		,							lowercase						:						List[Any]		,							lowercase						:						Optional[int]				)			->		Tuple:


    """simple docstring"""





    if not callable(__lowerCAmelCase				):
        raise ValueError("differentiate() requires a function as input for func"				)
    if not isinstance(__lowerCAmelCase		,							(float, int)				):
        raise ValueError("differentiate() requires a float as input for position"				)
    if not isinstance(__lowerCAmelCase		,							__lowerCAmelCase				):
        raise ValueError("differentiate() requires an int as input for order"				)
    snake_case					:   int         =					Dual(__lowerCAmelCase		,							1				)
    snake_case					:   Optional[int]         =					func(__lowerCAmelCase				)
    if order == 0:
        return result.real
    return result.duals[order - 1] * factorial(__lowerCAmelCase				)


if __name__ == "__main__":
  import doctest

  doctest.testmod()







  def 						__lowerCAmelCase		(		lowercase						:						Any				)			->		Any:


      """simple docstring"""





      return y**2 * y**4


  print(differentiate(f, 9, 2))









"""simple docstring"""



from __future__ import annotations

__snake_case         =					list[tuple[int, int]]

__snake_case         =					[
    [0, 0, 0, 0, 0, 0, 0],
    [0, 1, 0, 0, 0, 0, 0],  # 0 are free path whereas 1's are obstacles
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 1, 0, 0, 0, 0],
    [1, 0, 1, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 1, 0, 0],
]

__snake_case         =					([-1, 0], [0, -1], [1, 0], [0, 1])  # up, left, down, right







class _lowerCAmelCase       :







   def __init__(			self		,			UpperCamelCase__		,			UpperCamelCase__		,			UpperCamelCase__		,			UpperCamelCase__		,			UpperCamelCase__		,			UpperCamelCase__		,			)			->	str:

       '''simple docstring'''




       snake_case					:   int         =					pos_x
       snake_case					:   List[str]         =					pos_y
       snake_case					:   List[Any]         =					(pos_y, pos_x)
       snake_case					:   Optional[int]         =					goal_x
       snake_case					:   Dict         =					goal_y
       snake_case					:   Any         =					g_cost
       snake_case					:   List[Any]         =					parent
       snake_case					:   Union[str, Any]         =					self.calculate_heuristic()







   def 				lowerCamelCase	(			self		)			->	float:

       '''simple docstring'''




       snake_case					:   Optional[Any]         =					abs(self.pos_x - self.goal_x		)
       snake_case					:   Dict         =					abs(self.pos_y - self.goal_y		)
       return dx + dy







   def __lt__(			self		,			UpperCamelCase__		)			->	bool:

       '''simple docstring'''




       return self.f_cost < other.f_cost







class _lowerCAmelCase       :







   def __init__(			self		,			UpperCamelCase__		,			UpperCamelCase__		)			->	List[Any]:

       '''simple docstring'''




       snake_case					:   int         =					Node(start[1]		,			start[0]		,			goal[1]		,			goal[0]		,			0		,			UpperCamelCase__		)
       snake_case					:   List[Any]         =					Node(goal[1]		,			goal[0]		,			goal[1]		,			goal[0]		,			9_9999		,			UpperCamelCase__		)

       snake_case					:   Tuple         =					[self.start]
       snake_case					:   list[Node]         =					[]

       snake_case					:   Dict         =					False







   def 				lowerCamelCase	(			self		)			->	Path | None:

       '''simple docstring'''




       while self.open_nodes:
           # Open Nodes are sorted using __lt__
           self.open_nodes.sort()
           snake_case					:   str         =					self.open_nodes.pop(0		)

           if current_node.pos == self.target.pos:
               snake_case					:   Tuple         =					True
               return self.retrace_path(UpperCamelCase__		)

           self.closed_nodes.append(UpperCamelCase__		)
           snake_case					:   Optional[Any]         =					self.get_successors(UpperCamelCase__		)

           for child_node in successors:
               if child_node in self.closed_nodes:
                   continue

               if child_node not in self.open_nodes:
                   self.open_nodes.append(UpperCamelCase__		)
               else:
                   # retrieve the best current path
                   snake_case					:   Dict         =					self.open_nodes.pop(self.open_nodes.index(UpperCamelCase__		)		)

                   if child_node.g_cost < better_node.g_cost:
                       self.open_nodes.append(UpperCamelCase__		)
                   else:
                       self.open_nodes.append(UpperCamelCase__		)

       if not self.reached:
           return [self.start.pos]
       return None







   def 				lowerCamelCase	(			self		,			UpperCamelCase__		)			->	list[Node]:

       '''simple docstring'''




       snake_case					:   Dict         =					[]
       for action in delta:
           snake_case					:   Union[str, Any]         =					parent.pos_x + action[1]
           snake_case					:   str         =					parent.pos_y + action[0]

           if not (0 <= pos_x <= len(grid[0]		) - 1 and 0 <= pos_y <= len(UpperCamelCase__		) - 1):
               continue

           if grid[pos_y][pos_x] != 0:
               continue

           successors.append(
               Node(
                   UpperCamelCase__		,			UpperCamelCase__		,			self.target.pos_y		,			self.target.pos_x		,			parent.g_cost + 1		,			UpperCamelCase__		,			)		)
       return successors







   def 				lowerCamelCase	(			self		,			UpperCamelCase__		)			->	Path:

       '''simple docstring'''




       snake_case					:   Optional[int]         =					node
       snake_case					:   int         =					[]
       while current_node is not None:
           path.append((current_node.pos_y, current_node.pos_x)		)
           snake_case					:   Any         =					current_node.parent
       path.reverse()
       return path


if __name__ == "__main__":
  __snake_case         =					(0, 0)
  __snake_case         =					(len(grid) - 1, len(grid[0]) - 1)
  for elem in grid:
    print(elem)

  print("""------""")

  __snake_case         =					GreedyBestFirst(init, goal)
  __snake_case         =					greedy_bf.search()
  if path:
    for pos_x, pos_y in path:
      __snake_case         =					2

    for elem in grid:
      print(elem)





