


from __future__ import annotations

import time
from math import sqrt

# 1 for manhattan, 0 for euclidean
__snake_case									=		0

__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

__snake_case									=		tuple[int, int]



class      __lowerCamelCase       :







       def __init__(       self:      Any,A_:      int,A_:      int,A_:      int,A_:      int,A_:      int,A_:      Node | None,):






            '''simple docstring'''




            __UpperCamelCase      =       pos_x
            __UpperCamelCase      =       pos_y
            __UpperCamelCase      =       (pos_y, pos_x)
            __UpperCamelCase      =       goal_x
            __UpperCamelCase      =       goal_y
            __UpperCamelCase      =       g_cost
            __UpperCamelCase      =       parent
            __UpperCamelCase      =       self.calculate_heuristic()
            __UpperCamelCase      =       self.g_cost + self.h_cost







       def 						snake_case_     (       self:      List[str] ):






            '''simple docstring'''




            __UpperCamelCase      =       self.pos_x - self.goal_x
            __UpperCamelCase      =       self.pos_y - self.goal_y
            if HEURISTIC == 1:
                 return abs(_snake_case ) + abs(_snake_case )
            else:
                 return sqrt(dy**2 + dx**2 )







       def __lt__(       self:      Union[str, Any],A_:      Node ):






            '''simple docstring'''




            return self.f_cost < other.f_cost



class      __lowerCamelCase       :







       def __init__(       self:      str,A_:      TPosition,A_:      TPosition ):






            '''simple docstring'''




            __UpperCamelCase      =       Node(start[1],start[0],goal[1],goal[0],0,_snake_case )
            __UpperCamelCase      =       Node(goal[1],goal[0],goal[1],goal[0],9_9999,_snake_case )

            __UpperCamelCase      =       [self.start]
            __UpperCamelCase      =       []

            __UpperCamelCase      =       False







       def 						snake_case_     (       self:      Optional[int] ):






            '''simple docstring'''




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

                 if current_node.pos == self.target.pos:
                      return self.retrace_path(_snake_case )

                 self.closed_nodes.append(_snake_case )
                 __UpperCamelCase      =       self.get_successors(_snake_case )

                 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(_snake_case )
                      else:
                           # retrieve the best current path
                           __UpperCamelCase      =       self.open_nodes.pop(self.open_nodes.index(_snake_case ) )

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

            return [self.start.pos]







       def 						snake_case_     (       self:      Tuple,A_:      Node ):






            '''simple docstring'''




            __UpperCamelCase      =       []
            for action in delta:
                 __UpperCamelCase      =       parent.pos_x + action[1]
                 __UpperCamelCase      =       parent.pos_y + action[0]
                 if not (0 <= pos_x <= len(grid[0] ) - 1 and 0 <= pos_y <= len(_snake_case ) - 1):
                      continue

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

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







       def 						snake_case_     (       self:      Any,A_:      Node | None ):






            '''simple docstring'''




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



class      __lowerCamelCase       :







       def __init__(       self:      Any,A_:      TPosition,A_:      TPosition ):






            '''simple docstring'''




            __UpperCamelCase      =       AStar(_snake_case,_snake_case )
            __UpperCamelCase      =       AStar(_snake_case,_snake_case )
            __UpperCamelCase      =       False







       def 						snake_case_     (       self:      List[Any] ):






            '''simple docstring'''




            while self.fwd_astar.open_nodes or self.bwd_astar.open_nodes:
                 self.fwd_astar.open_nodes.sort()
                 self.bwd_astar.open_nodes.sort()
                 __UpperCamelCase      =       self.fwd_astar.open_nodes.pop(0 )
                 __UpperCamelCase      =       self.bwd_astar.open_nodes.pop(0 )

                 if current_bwd_node.pos == current_fwd_node.pos:
                      return self.retrace_bidirectional_path(
                          _snake_case,_snake_case )

                 self.fwd_astar.closed_nodes.append(_snake_case )
                 self.bwd_astar.closed_nodes.append(_snake_case )

                 __UpperCamelCase      =       current_bwd_node
                 __UpperCamelCase      =       current_fwd_node

                 __UpperCamelCase      =       {
                     self.fwd_astar: self.fwd_astar.get_successors(_snake_case ),
                     self.bwd_astar: self.bwd_astar.get_successors(_snake_case ),
                 }

                 for astar in [self.fwd_astar, self.bwd_astar]:
                      for child_node in successors[astar]:
                           if child_node in astar.closed_nodes:
                                continue

                           if child_node not in astar.open_nodes:
                                astar.open_nodes.append(_snake_case )
                           else:
                                # retrieve the best current path
                                __UpperCamelCase      =       astar.open_nodes.pop(
                                    astar.open_nodes.index(_snake_case ) )

                                if child_node.g_cost < better_node.g_cost:
                                     astar.open_nodes.append(_snake_case )
                                else:
                                     astar.open_nodes.append(_snake_case )

            return [self.fwd_astar.start.pos]







       def 						snake_case_     (       self:      int,A_:      Node,A_:      Node ):






            '''simple docstring'''




            __UpperCamelCase      =       self.fwd_astar.retrace_path(_snake_case )
            __UpperCamelCase      =       self.bwd_astar.retrace_path(_snake_case )
            bwd_path.pop()
            bwd_path.reverse()
            __UpperCamelCase      =       fwd_path + bwd_path
            return path


if __name__ == "__main__":
    # all coordinates are given in format [y,x]
    __snake_case									=		(0, 0)
    __snake_case									=		(len(grid) - 1, len(grid[0]) - 1)
    for elem in grid:
        print(elem)

    __snake_case									=		time.time()
    __snake_case									=		AStar(init, goal)
    __snake_case									=		a_star.search()
    __snake_case									=		time.time() - start_time
    print(f"""AStar execution time = {end_time:f} seconds""")

    __snake_case									=		time.time()
    __snake_case									=		BidirectionalAStar(init, goal)
    __snake_case									=		time.time() - bd_start_time
    print(f"""BidirectionalAStar execution time = {bd_end_time:f} seconds""")








from datetime import datetime

import requests


def    A						(__A   :    str       )   ->      bytes:







     """simple docstring"""


     UpperCAmelCase_          =							'''https://downloadgram.net/wp-json/wppress/video-downloader/video?url='''
     UpperCAmelCase_          =							requests.get(base_url + url       ).json()[0]['''urls'''][0]['''src''']
     return requests.get(__A       ).content


if __name__ == "__main__":
    snake_case_ : Optional[Any]    		=       input("Enter Video/IGTV url: ").strip()
    snake_case_ : Any    		=       f"{datetime.now():%Y-%m-%d_%H:%M:%S}.mp4"
    with open(file_name, "wb") as fp:
        fp.write(download_video(url))
    print(f"Done. Video saved to disk as {file_name}.")






