
"""simple docstring"""




import heapq
import sys

import numpy as np

a		:       Dict     						=       tuple[int, int]







class     lowercase:



     def __init__(							self   )		->     Tuple:







         """simple docstring"""



         a__		=			[]
         a__		=			set()



     def 			lowercase__  (							self   )		->     List[Any]:







         """simple docstring"""



         if not self.empty():
             return self.elements[0][0]
         else:
             return float('inf'   )



     def 			lowercase__  (							self   )		->     Optional[Any]:







         """simple docstring"""



         return len(self.elements   ) == 0



     def 			lowercase__  (							self     ,				__SCREAMING_SNAKE_CASE     ,				__SCREAMING_SNAKE_CASE   )		->     Optional[Any]:







         """simple docstring"""



         if item not in self.set:
             heapq.heappush(self.elements     ,				(priority, item)   )
             self.set.add(lowercase_   )
         else:
             # update
             # print("update", item)
             a__		=			[]
             ((a__)	,     (a__))		=			heapq.heappop(self.elements   )
             while x != item:
                 temp.append((pri, x)   )
                 ((a__)	,     (a__))		=			heapq.heappop(self.elements   )
             temp.append((priority, item)   )
             for pro, xxx in temp:
                 heapq.heappush(self.elements     ,				(pro, xxx)   )



     def 			lowercase__  (							self     ,				__SCREAMING_SNAKE_CASE   )		->     Dict:







         """simple docstring"""



         if item in self.set:
             self.set.remove(lowercase_   )
             a__		=			[]
             ((a__)	,     (a__))		=			heapq.heappop(self.elements   )
             while x != item:
                 temp.append((pro, x)   )
                 ((a__)	,     (a__))		=			heapq.heappop(self.elements   )
             for prito, yyy in temp:
                 heapq.heappush(self.elements     ,				(prito, yyy)   )



     def 			lowercase__  (							self   )		->     Optional[Any]:







         """simple docstring"""



         return self.elements[0][1]




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







         """simple docstring"""



         ((a__)	,     (a__))		=			heapq.heappop(self.elements   )
         self.set.remove(lowercase_   )
         return (priority, item)




def     __magic_name__		(					UpperCamelCase     :		Union[str, Any]							,		UpperCamelCase     :		int     )     ->						Any:
    a__		=			np.array(__UpperCAmelCase     )
    a__		=			np.array(__UpperCAmelCase     )
    return np.linalg.norm(a - b     )



def     __magic_name__		(					UpperCamelCase     :		Any							,		UpperCamelCase     :		str     )     ->						int:
    return consistent_heuristic(__UpperCAmelCase							,		__UpperCAmelCase     ) // t



def     __magic_name__		(					UpperCamelCase     :		str							,		UpperCamelCase     :		Union[str, Any]     )     ->						List[str]:
    return abs(p[0] - goal[0]     ) + abs(p[1] - goal[1]     )



def     __magic_name__		(					UpperCamelCase     :		List[Any]							,		UpperCamelCase     :		Tuple							,		UpperCamelCase     :		List[str]							,		UpperCamelCase     :		int     )     ->						Optional[int]:
    a__		=			g_function[start] + Wa * heuristics[i](__UpperCAmelCase							,		__UpperCAmelCase     )
    return ans



def     __magic_name__		(					UpperCamelCase     :		Dict							,		UpperCamelCase     :		Dict							,		UpperCamelCase     :		Union[str, Any]     )     ->						Optional[Any]:
    a__		=			np.chararray((n, n)     )
    for i in range(__UpperCAmelCase     ):
        for j in range(__UpperCAmelCase     ):
            a__		=			'*'

    for i in range(__UpperCAmelCase     ):
        for j in range(__UpperCAmelCase     ):
            if (j, (n - 1) - i) in blocks:
                a__		=			'#'

    a__		=			'-'
    a__		=			back_pointer[goal]
    while x != start:
        ((a__)	,     (a__))		=			x
        # print(x)
        a__		=			'-'
        a__		=			back_pointer[x]
    a__		=			'-'

    for i in range(__UpperCAmelCase     ):
        for j in range(__UpperCAmelCase     ):
            if (i, j) == (0, n - 1):
                print(grid[i][j]							,		end=' '     )
                print('<-- End position'							,		end=' '     )
            else:
                print(grid[i][j]							,		end=' '     )
        print()
    print('^'     )
    print('Start position'     )
    print()
    print('# is an obstacle'     )
    print('- is the path taken by algorithm'     )
    print('PATH TAKEN BY THE ALGORITHM IS:-'     )
    a__		=			back_pointer[goal]
    while x != start:
        print(__UpperCAmelCase							,		end=' '     )
        a__		=			back_pointer[x]
    print(__UpperCAmelCase     )
    sys.exit()



def     __magic_name__		(					UpperCamelCase     :		List[Any]     )     ->						int:

    if p[0] < 0 or p[0] > n - 1:
        return False
    if p[1] < 0 or p[1] > n - 1:
        return False
    return True



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

    for itera in range(__UpperCAmelCase     ):
        open_list[itera].remove_element(__UpperCAmelCase     )
    # print("s", s)
    # print("j", j)
    ((a__)	,     (a__))		=			s
    a__		=			(x - 1, y)
    a__		=			(x + 1, y)
    a__		=			(x, y + 1)
    a__		=			(x, y - 1)

    for neighbours in [left, right, up, down]:
        if neighbours not in blocks:
            if valid(__UpperCAmelCase     ) and neighbours not in visited:
                # print("neighbour", neighbours)
                visited.add(__UpperCAmelCase     )
                a__		=			-1
                a__		=			float('inf'     )

            if valid(__UpperCAmelCase     ) and g_function[neighbours] > g_function[s] + 1:
                a__		=			g_function[s] + 1
                a__		=			s
                if neighbours not in close_list_anchor:
                    open_list[0].put(__UpperCAmelCase							,		key(__UpperCAmelCase							,		0							,		__UpperCAmelCase							,		__UpperCAmelCase     )     )
                    if neighbours not in close_list_inad:
                        for var in range(1							,		__UpperCAmelCase     ):
                            if key(__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase     ) <= Wa * key(
                                __UpperCAmelCase							,		0							,		__UpperCAmelCase							,		__UpperCAmelCase     ):
                                open_list[j].put(
                                    __UpperCAmelCase							,		key(__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase     )     )



def     __magic_name__		(					)     ->						str:
    a__		=			[]
    for x in range(1							,		5     ):
        for y in range(1							,		6     ):
            some_list.append((x, y)     )

    for x in range(15							,		20     ):
        some_list.append((x, 17)     )

    for x in range(10							,		19     ):
        for y in range(1							,		15     ):
            some_list.append((x, y)     )

    # L block
    for x in range(1							,		4     ):
        for y in range(12							,		19     ):
            some_list.append((x, y)     )
    for x in range(3							,		13     ):
        for y in range(16							,		19     ):
            some_list.append((x, y)     )
    return some_list


a		:       Tuple     						=       {0: consistent_heuristic, 1: heuristic_a, 2: heuristic_a}

a		:       Dict     						=       [
    (0, 1),
    (1, 1),
    (2, 1),
    (3, 1),
    (4, 1),
    (5, 1),
    (6, 1),
    (7, 1),
    (8, 1),
    (9, 1),
    (10, 1),
    (11, 1),
    (12, 1),
    (13, 1),
    (14, 1),
    (15, 1),
    (16, 1),
    (17, 1),
    (18, 1),
    (19, 1),
]
a		:       List[str]     						=       make_common_ground()


a		:       Optional[int]     						=       blocks_blk
# hyper parameters
a		:       Union[str, Any]     						=       1
a		:       str     						=       1
a		:       int     						=       20
a		:       Optional[int]     						=       3  # one consistent and two other inconsistent

# start and end destination
a		:       List[str]     						=       (0, 0)
a		:       str     						=       (n - 1, n - 1)

a		:       str     						=       1



def     __magic_name__		(					UpperCamelCase     :		Dict							,		UpperCamelCase     :		Optional[int]							,		UpperCamelCase     :		Tuple     )     ->						List[str]:
    a__		=			{start: 0, goal: float('inf'     )}
    a__		=			{start: -1, goal: -1}
    a__		=			[]
    a__		=			set()

    for i in range(__UpperCAmelCase     ):
        open_list.append(PriorityQueue()     )
        open_list[i].put(__UpperCAmelCase							,		key(__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase     )     )

    a__		=			[]
    a__		=			[]
    while open_list[0].minkey() < float('inf'     ):
        for i in range(1							,		__UpperCAmelCase     ):
            # print(open_list[0].minkey(), open_list[i].minkey())
            if open_list[i].minkey() <= Wa * open_list[0].minkey():
                global t
                t += 1
                if g_function[goal] <= open_list[i].minkey():
                    if g_function[goal] < float('inf'     ):
                        do_something(__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase     )
                else:
                    a__	,     a__		=			open_list[i].top_show()
                    visited.add(__UpperCAmelCase     )
                    expand_state(
                        __UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase							,		)
                    close_list_inad.append(__UpperCAmelCase     )
            else:
                if g_function[goal] <= open_list[0].minkey():
                    if g_function[goal] < float('inf'     ):
                        do_something(__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase     )
                else:
                    a__		=			open_list[0].top_show()
                    visited.add(__UpperCAmelCase     )
                    expand_state(
                        __UpperCAmelCase							,		0							,		__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase							,		__UpperCAmelCase							,		)
                    close_list_anchor.append(__UpperCAmelCase     )
    print('No path found to goal'     )
    print()
    for i in range(n - 1							,		-1							,		-1     ):
        for j in range(__UpperCAmelCase     ):
            if (j, i) in blocks:
                print('#'							,		end=' '     )
            elif (j, i) in back_pointer:
                if (j, i) == (n - 1, n - 1):
                    print('*'							,		end=' '     )
                else:
                    print('-'							,		end=' '     )
            else:
                print('*'							,		end=' '     )
            if (j, i) == (n - 1, n - 1):
                print('<-- End position'							,		end=' '     )
        print()
    print('^'     )
    print('Start position'     )
    print()
    print('# is an obstacle'     )
    print('- is the path taken by algorithm'     )


if __name__ == "__main__":
    multi_a_star(start, goal, n_heuristic)








'''simple docstring'''

import heapq
import sys

import numpy as np

a    :							Dict										=    tuple[int, int]






class 		a							:


				def __init__(						self       :   Dict   ):
									snake_case_		     =							[]
									snake_case_		     =							set()


				def     A_					(						self       :   int   ):
									if not self.empty():
														return self.elements[0][0]
									else:
														return float('''inf'''   )


				def     A_					(						self       :   List[str]   ):
									return len(self.elements   ) == 0


				def     A_					(						self       :   Union[str, Any]			,							lowercase_       :   str			,							lowercase_       :   List[str]   ):
									if item not in self.set:
														heapq.heappush(self.elements			,							(priority, item)   )
														self.set.add(lowercase_   )
									else:
														# update
														# print("update", item)
														snake_case_		     =							[]
														((snake_case_)     ,(snake_case_))		     =							heapq.heappop(self.elements   )
														while x != item:
																			temp.append((pri, x)   )
																			((snake_case_)     ,(snake_case_))		     =							heapq.heappop(self.elements   )
														temp.append((priority, item)   )
														for pro, xxx in temp:
																			heapq.heappush(self.elements			,							(pro, xxx)   )


				def     A_					(						self       :   Union[str, Any]			,							lowercase_       :   List[Any]   ):
									if item in self.set:
														self.set.remove(lowercase_   )
														snake_case_		     =							[]
														((snake_case_)     ,(snake_case_))		     =							heapq.heappop(self.elements   )
														while x != item:
																			temp.append((pro, x)   )
																			((snake_case_)     ,(snake_case_))		     =							heapq.heappop(self.elements   )
														for prito, yyy in temp:
																			heapq.heappush(self.elements			,							(prito, yyy)   )


				def     A_					(						self       :   Optional[int]   ):
									return self.elements[0][1]


				def     A_					(						self       :   Tuple   ):
									((snake_case_)     ,(snake_case_))		     =							heapq.heappop(self.elements   )
									self.set.remove(lowercase_   )
									return (priority, item)







def 						__magic_name__       (      __UpperCAmelCase, __UpperCAmelCase      )						->   Any:

					'''simple docstring'''

					snake_case_		     =							np.array(__UpperCAmelCase      )
					snake_case_		     =							np.array(__UpperCAmelCase      )
					return np.linalg.norm(a - b      )


def 						__magic_name__       (      __UpperCAmelCase, __UpperCAmelCase      )						->   int:

					'''simple docstring'''

					return consistent_heuristic(__UpperCAmelCase, __UpperCAmelCase      ) // t


def 						__magic_name__       (      __UpperCAmelCase, __UpperCAmelCase      )						->   List[str]:

					'''simple docstring'''

					return abs(p[0] - goal[0]      ) + abs(p[1] - goal[1]      )


def 						__magic_name__       (      __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase      )						->   Optional[int]:

					'''simple docstring'''

					snake_case_		     =							g_function[start] + Wa * heuristics[i](__UpperCAmelCase, __UpperCAmelCase      )
					return ans


def 						__magic_name__       (      __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase      )						->   Optional[Any]:

					'''simple docstring'''

					snake_case_		     =							np.chararray((n, n)      )
					for i in range(__UpperCAmelCase      ):
										for j in range(__UpperCAmelCase      ):
															snake_case_		     =							'''*'''

					for i in range(__UpperCAmelCase      ):
										for j in range(__UpperCAmelCase      ):
															if (j, (n - 1) - i) in blocks:
																				snake_case_		     =							'''#'''

					snake_case_		     =							'''-'''
					snake_case_		     =							back_pointer[goal]
					while x != start:
										((snake_case_)     ,(snake_case_))		     =							x
										# print(x)
										snake_case_		     =							'''-'''
										snake_case_		     =							back_pointer[x]
					snake_case_		     =							'''-'''

					for i in range(__UpperCAmelCase      ):
										for j in range(__UpperCAmelCase      ):
															if (i, j) == (0, n - 1):
																				print(grid[i][j], end=''' '''      )
																				print('''<-- End position''', end=''' '''      )
															else:
																				print(grid[i][j], end=''' '''      )
										print()
					print('''^'''      )
					print('''Start position'''      )
					print()
					print('''# is an obstacle'''      )
					print('''- is the path taken by algorithm'''      )
					print('''PATH TAKEN BY THE ALGORITHM IS:-'''      )
					snake_case_		     =							back_pointer[goal]
					while x != start:
										print(__UpperCAmelCase, end=''' '''      )
										snake_case_		     =							back_pointer[x]
					print(__UpperCAmelCase      )
					sys.exit()


def 						__magic_name__       (      __UpperCAmelCase      )						->   int:

					'''simple docstring'''

					if p[0] < 0 or p[0] > n - 1:
										return False
					if p[1] < 0 or p[1] > n - 1:
										return False
					return True


def 						__magic_name__       (      __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, )						->   str:

					'''simple docstring'''

					for itera in range(__UpperCAmelCase      ):
										open_list[itera].remove_element(__UpperCAmelCase      )
					# print("s", s)
					# print("j", j)
					((snake_case_)     ,(snake_case_))		     =							s
					snake_case_		     =							(x - 1, y)
					snake_case_		     =							(x + 1, y)
					snake_case_		     =							(x, y + 1)
					snake_case_		     =							(x, y - 1)

					for neighbours in [left, right, up, down]:
										if neighbours not in blocks:
															if valid(__UpperCAmelCase      ) and neighbours not in visited:
																				# print("neighbour", neighbours)
																				visited.add(__UpperCAmelCase      )
																				snake_case_		     =							-1
																				snake_case_		     =							float('''inf'''      )

															if valid(__UpperCAmelCase      ) and g_function[neighbours] > g_function[s] + 1:
																				snake_case_		     =							g_function[s] + 1
																				snake_case_		     =							s
																				if neighbours not in close_list_anchor:
																									open_list[0].put(__UpperCAmelCase, key(__UpperCAmelCase, 0, __UpperCAmelCase, __UpperCAmelCase      )      )
																									if neighbours not in close_list_inad:
																														for var in range(1, __UpperCAmelCase      ):
																																			if key(__UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase      ) <= Wa * key(
																																			    __UpperCAmelCase, 0, __UpperCAmelCase, __UpperCAmelCase      ):
																																								open_list[j].put(
																																								    __UpperCAmelCase, key(__UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase      )      )


def 						__magic_name__       (      )						->   str:

					'''simple docstring'''

					snake_case_		     =							[]
					for x in range(1, 5      ):
										for y in range(1, 6      ):
															some_list.append((x, y)      )

					for x in range(15, 20      ):
										some_list.append((x, 17)      )

					for x in range(10, 19      ):
										for y in range(1, 15      ):
															some_list.append((x, y)      )

    # L block
					for x in range(1, 4      ):
										for y in range(12, 19      ):
															some_list.append((x, y)      )
					for x in range(3, 13      ):
										for y in range(16, 19      ):
															some_list.append((x, y)      )
					return some_list


a    :							Tuple										=    {0: consistent_heuristic, 1: heuristic_a, 2: heuristic_a}

a    :							Dict										=    [
    (0, 1),
    (1, 1),
    (2, 1),
    (3, 1),
    (4, 1),
    (5, 1),
    (6, 1),
    (7, 1),
    (8, 1),
    (9, 1),
    (10, 1),
    (11, 1),
    (12, 1),
    (13, 1),
    (14, 1),
    (15, 1),
    (16, 1),
    (17, 1),
    (18, 1),
    (19, 1),
]
a    :							List[str]										=    make_common_ground()


a    :							Optional[int]										=    blocks_blk
# hyper parameters
a    :							Union[str, Any]										=    1
a    :							str										=    1
a    :							int										=    20
a    :							Optional[int]										=    3  # one consistent and two other inconsistent

# start and end destination
a    :							List[str]										=    (0, 0)
a    :							str										=    (n - 1, n - 1)

a    :							str										=    1


def 						__magic_name__       (      __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase      )						->   List[str]:

					'''simple docstring'''

					snake_case_		     =							{start: 0, goal: float('''inf'''      )}
					snake_case_		     =							{start: -1, goal: -1}
					snake_case_		     =							[]
					snake_case_		     =							set()

					for i in range(__UpperCAmelCase      ):
										open_list.append(PriorityQueue()      )
										open_list[i].put(__UpperCAmelCase, key(__UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase      )      )

					snake_case_		     =							[]
					snake_case_		     =							[]
					while open_list[0].minkey() < float('''inf'''      ):
										for i in range(1, __UpperCAmelCase      ):
															# print(open_list[0].minkey(), open_list[i].minkey())
															if open_list[i].minkey() <= Wa * open_list[0].minkey():
																				global t
																				t += 1
																				if g_function[goal] <= open_list[i].minkey():
																									if g_function[goal] < float('''inf'''      ):
																														do_something(__UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase      )
																				else:
																									snake_case_     ,snake_case_		     =							open_list[i].top_show()
																									visited.add(__UpperCAmelCase      )
																									expand_state(
																									    __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, )
																									close_list_inad.append(__UpperCAmelCase      )
															else:
																				if g_function[goal] <= open_list[0].minkey():
																									if g_function[goal] < float('''inf'''      ):
																														do_something(__UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase      )
																				else:
																									snake_case_		     =							open_list[0].top_show()
																									visited.add(__UpperCAmelCase      )
																									expand_state(
																									    __UpperCAmelCase, 0, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, __UpperCAmelCase, )
																									close_list_anchor.append(__UpperCAmelCase      )
					print('''No path found to goal'''      )
					print()
					for i in range(n - 1, -1, -1      ):
										for j in range(__UpperCAmelCase      ):
															if (j, i) in blocks:
																				print('''#''', end=''' '''      )
															elif (j, i) in back_pointer:
																				if (j, i) == (n - 1, n - 1):
																									print('''*''', end=''' '''      )
																				else:
																									print('''-''', end=''' '''      )
															else:
																				print('''*''', end=''' '''      )
															if (j, i) == (n - 1, n - 1):
																				print('''<-- End position''', end=''' '''      )
										print()
					print('''^'''      )
					print('''Start position'''      )
					print()
					print('''# is an obstacle'''      )
					print('''- is the path taken by algorithm'''      )


if __name__ == "__main__":
							multi_a_star(start, goal, n_heuristic)

