


"""simple docstring"""




import unittest

from .lib import (
    Matrix,
    Vector,
    axpy,
    square_zero_matrix,
    unit_basis_vector,
    zero_vector,
)







class lowerCAmelCase_						(			unittest.TestCase	):

 '''simple docstring'''

 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Vector([1, 2, 3] )
       self.assertEqual(x.component(0 )		,				1 )
       self.assertEqual(x.component(2 )		,				3 )
       snake_case_	=				Vector()



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Vector([0, 0, 0, 0, 0, 1] )
       self.assertEqual(str(_UpperCAmelCase )		,				'''(0,0,0,0,0,1)''' )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Vector([1, 2, 3, 4] )
       self.assertEqual(len(_UpperCAmelCase )		,				4 )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Vector([1, 2] )
       snake_case_	=				Vector([1, 2, 3, 4, 5] )
       snake_case_	=				Vector([0, 0, 0, 0, 0, 0, 0, 0, 0, 0] )
       snake_case_	=				Vector([1, -1, 1, -1, 2, -3, 4, -5] )
       self.assertAlmostEqual(x.euclidean_length()		,				2.236		,				3 )
       self.assertAlmostEqual(y.euclidean_length()		,				7.416		,				3 )
       self.assertEqual(z.euclidean_length()		,				0 )
       self.assertAlmostEqual(w.euclidean_length()		,				7.616		,				3 )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Vector([1, 2, 3] )
       snake_case_	=				Vector([1, 1, 1] )
       self.assertEqual((x + y).component(0 )		,				2 )
       self.assertEqual((x + y).component(1 )		,				3 )
       self.assertEqual((x + y).component(2 )		,				4 )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Vector([1, 2, 3] )
       snake_case_	=				Vector([1, 1, 1] )
       self.assertEqual((x - y).component(0 )		,				0 )
       self.assertEqual((x - y).component(1 )		,				1 )
       self.assertEqual((x - y).component(2 )		,				2 )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Vector([1, 2, 3] )
       snake_case_	=				Vector([2, -1, 4] )  # for test of dot product
       snake_case_	=				Vector([1, -2, -1] )
       self.assertEqual(str(x * 3.0 )		,				'''(3.0,6.0,9.0)''' )
       self.assertEqual((a * b)		,				0 )



 def 						UpperCamelCase__					(     self ):
       self.assertEqual(str(zero_vector(10 ) ).count('''0''' )		,				10 )



 def 						UpperCamelCase__					(     self ):
       self.assertEqual(str(unit_basis_vector(3		,				1 ) )		,				'''(0,1,0)''' )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Vector([1, 2, 3] )
       snake_case_	=				Vector([1, 0, 1] )
       self.assertEqual(str(axpy(2		,				_UpperCAmelCase		,				_UpperCAmelCase ) )		,				'''(3,4,7)''' )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Vector([1, 0, 0, 0, 0, 0] )
       snake_case_	=				x.copy()
       self.assertEqual(str(_UpperCAmelCase )		,				str(_UpperCAmelCase ) )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Vector([1, 0, 0] )
       x.change_component(0		,				0 )
       x.change_component(1		,				1 )
       self.assertEqual(str(_UpperCAmelCase )		,				'''(0,1,0)''' )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]		,				3		,				3 )
       self.assertEqual('''|1,2,3|\n|2,4,5|\n|6,7,8|\n'''		,				str(_UpperCAmelCase ) )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]		,				3		,				3 )
       snake_case_	=				[[-3, -14, -10], [-5, -10, -5], [-2, -1, 0]]
       for x in range(a.height() ):
             for y in range(a.width() ):
                   self.assertEqual(minors[x][y]		,				a.minor(_UpperCAmelCase		,				_UpperCAmelCase ) )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]		,				3		,				3 )
       snake_case_	=				[[-3, 14, -10], [5, -10, 5], [-2, 1, 0]]
       for x in range(a.height() ):
             for y in range(a.width() ):
                   self.assertEqual(cofactors[x][y]		,				a.cofactor(_UpperCAmelCase		,				_UpperCAmelCase ) )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]		,				3		,				3 )
       self.assertEqual(-5		,				a.determinant() )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]		,				3		,				3 )
       snake_case_	=				Vector([1, 2, 3] )
       self.assertEqual('''(14,32,50)'''		,				str(a * x ) )
       self.assertEqual('''|2,4,6|\n|8,10,12|\n|14,16,18|\n'''		,				str(a * 2 ) )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]		,				3		,				3 )
       a.change_component(0		,				2		,				5 )
       self.assertEqual('''|1,2,5|\n|2,4,5|\n|6,7,8|\n'''		,				str(_UpperCAmelCase ) )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]		,				3		,				3 )
       self.assertEqual(7		,				a.component(2		,				1 )		,				0.01 )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]		,				3		,				3 )
       snake_case_	=				Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]]		,				3		,				3 )
       self.assertEqual('''|2,4,10|\n|4,8,10|\n|12,14,18|\n'''		,				str(a + b ) )



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				Matrix([[1, 2, 3], [2, 4, 5], [6, 7, 8]]		,				3		,				3 )
       snake_case_	=				Matrix([[1, 2, 7], [2, 4, 5], [6, 7, 10]]		,				3		,				3 )
       self.assertEqual('''|0,0,-4|\n|0,0,0|\n|0,0,-2|\n'''		,				str(a - b ) )





 def 						UpperCamelCase__					(     self ):
       self.assertEqual(
           '''|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n|0,0,0,0,0|\n'''		,				str(square_zero_matrix(5 ) )		,				)


if __name__ == "__main__":
   unittest.main()



from __future__ import annotations

import time

UpperCAmelCase      =   list[tuple[int, int]]

UpperCAmelCase      =   [
    [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],
]

UpperCAmelCase      =   [[-1, 0], [0, -1], [1, 0], [0, 1]]  # up, left, down, right







class lowerCAmelCase_						:

 '''simple docstring'''

 def __init__(     self		,				_UpperCAmelCase		,				_UpperCAmelCase		,				_UpperCAmelCase		,				_UpperCAmelCase		,				_UpperCAmelCase ):
       snake_case_	=				pos_x
       snake_case_	=				pos_y
       snake_case_	=				(pos_y, pos_x)
       snake_case_	=				goal_x
       snake_case_	=				goal_y
       snake_case_	=				parent







class lowerCAmelCase_						:

 '''simple docstring'''

 def __init__(     self		,				_UpperCAmelCase		,				_UpperCAmelCase ):
       snake_case_	=				Node(start[1]		,				start[0]		,				goal[1]		,				goal[0]		,				_UpperCAmelCase )
       snake_case_	=				Node(goal[1]		,				goal[0]		,				goal[1]		,				goal[0]		,				_UpperCAmelCase )

       snake_case_	=				[self.start]
       snake_case_	=				False



 def 						UpperCamelCase__					(     self ):
       while self.node_queue:
             snake_case_	=				self.node_queue.pop(0 )

             if current_node.pos == self.target.pos:
                   snake_case_	=				True
                   return self.retrace_path(_UpperCAmelCase )

             snake_case_	=				self.get_successors(_UpperCAmelCase )

             for node in successors:
                   self.node_queue.append(_UpperCAmelCase )

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



 def 						UpperCamelCase__					(     self		,				_UpperCAmelCase ):
       snake_case_	=				[]
       for action in delta:
             snake_case_	=				parent.pos_x + action[1]
             snake_case_	=				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		,				_UpperCAmelCase ) )
       return successors





 def 						UpperCamelCase__					(     self		,				_UpperCAmelCase ):
       snake_case_	=				node
       snake_case_	=				[]
       while current_node is not None:
             path.append((current_node.pos_y, current_node.pos_x) )
             snake_case_	=				current_node.parent
       path.reverse()
       return path







class lowerCAmelCase_						:

 '''simple docstring'''

 def __init__(     self		,				_UpperCAmelCase		,				_UpperCAmelCase ):
       snake_case_	=				BreadthFirstSearch(_UpperCAmelCase		,				_UpperCAmelCase )
       snake_case_	=				BreadthFirstSearch(_UpperCAmelCase		,				_UpperCAmelCase )
       snake_case_	=				False



 def 						UpperCamelCase__					(     self ):
       while self.fwd_bfs.node_queue or self.bwd_bfs.node_queue:
             snake_case_	=				self.fwd_bfs.node_queue.pop(0 )
             snake_case_	=				self.bwd_bfs.node_queue.pop(0 )

             if current_bwd_node.pos == current_fwd_node.pos:
                   snake_case_	=				True
                   return self.retrace_bidirectional_path(
                       _UpperCAmelCase		,				_UpperCAmelCase )

             snake_case_	=				current_bwd_node
             snake_case_	=				current_fwd_node

             snake_case_	=				{
                 self.fwd_bfs: self.fwd_bfs.get_successors(_UpperCAmelCase ),
                 self.bwd_bfs: self.bwd_bfs.get_successors(_UpperCAmelCase ),
             }

             for bfs in [self.fwd_bfs, self.bwd_bfs]:
                   for node in successors[bfs]:
                         bfs.node_queue.append(_UpperCAmelCase )

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





 def 						UpperCamelCase__					(     self		,				_UpperCAmelCase		,				_UpperCAmelCase ):
       snake_case_	=				self.fwd_bfs.retrace_path(_UpperCAmelCase )
       snake_case_	=				self.bwd_bfs.retrace_path(_UpperCAmelCase )
       bwd_path.pop()
       bwd_path.reverse()
       snake_case_	=				fwd_path + bwd_path
       return path


if __name__ == "__main__":
   # all coordinates are given in format [y,x]
   import doctest

   doctest.testmod()
   UpperCAmelCase      =   (0, 0)
   UpperCAmelCase      =   (len(grid) - 1, len(grid[0]) - 1)
   for elem in grid:
      print(elem)

   UpperCAmelCase      =   time.time()
   UpperCAmelCase      =   BreadthFirstSearch(init, goal)
   UpperCAmelCase      =   bfs.search()
   UpperCAmelCase      =   time.time() - start_bfs_time

   print("""Unidirectional BFS computation time : """, bfs_time)

   UpperCAmelCase      =   time.time()
   UpperCAmelCase      =   BidirectionalBreadthFirstSearch(init, goal)
   UpperCAmelCase      =   bd_bfs.search()
   UpperCAmelCase      =   time.time() - start_bd_bfs_time

   print("""Bidirectional BFS computation time : """, bd_bfs_time)