






'''simple docstring'''
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 							_UpperCAmelCase    :




    def __init__(      self	:							int	,  a	:							int	,  a	:							int	,  a	:							int	,  a	:							int	,  a	:							Node | None      ):






       '''simple docstring'''






       lowercase_						:     List[Any]							     =  pos_x
       lowercase_						:     Dict							     =  pos_y
       lowercase_						:     Tuple							     =  (pos_y, pos_x)
       lowercase_						:     int							     =  goal_x
       lowercase_						:     Union[str, Any]							     =  goal_y
       lowercase_						:     int							     =  parent


class 							_UpperCAmelCase    :




    def __init__(      self	:							List[Any]	,  a	:							tuple[int, int]	,  a	:							tuple[int, int]      ):






       '''simple docstring'''






       lowercase_						:     Tuple							     =  Node(start[1]	,  start[0]	,  goal[1]	,  goal[0]	,  a      )
       lowercase_						:     List[Any]							     =  Node(goal[1]	,  goal[0]	,  goal[1]	,  goal[0]	,  a      )

       lowercase_						:     Union[str, Any]							     =  [self.start]
       lowercase_						:     List[Any]							     =  False




    def 					lowerCAmelCase__					(      self	:							Tuple      ):






       '''simple docstring'''






       while self.node_queue:
          lowercase_						:     List[str]							     =  self.node_queue.pop(0      )

          if current_node.pos == self.target.pos:
             lowercase_						:     Optional[Any]							     =  True
             return self.retrace_path(a      )

          lowercase_						:     Dict							     =  self.get_successors(a      )

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

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




    def 					lowerCAmelCase__					(      self	:							int	,  a	:							Node      ):






       '''simple docstring'''






       lowercase_						:     List[Any]							     =  []
       for action in delta:
          lowercase_						:     str							     =  parent.pos_x + action[1]
          lowercase_						:     Dict							     =  parent.pos_y + action[0]
          if not (0 <= pos_x <= len(grid[0]      ) - 1 and 0 <= pos_y <= len(a      ) - 1):
             continue

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

          successors.append(
              Node(a	,  a	,  self.target.pos_y	,  self.target.pos_x	,  a      )      )
       return successors





    def 					lowerCAmelCase__					(      self	:							Tuple	,  a	:							Node | None      ):






       '''simple docstring'''






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


class 							_UpperCAmelCase    :




    def __init__(      self	:							List[str]	,  a	:							int	,  a	:							int      ):






       '''simple docstring'''






       lowercase_						:     Optional[int]							     =  BreadthFirstSearch(a	,  a      )
       lowercase_						:     Optional[Any]							     =  BreadthFirstSearch(a	,  a      )
       lowercase_						:     str							     =  False




    def 					lowerCAmelCase__					(      self	:							Any      ):






       '''simple docstring'''






       while self.fwd_bfs.node_queue or self.bwd_bfs.node_queue:
          lowercase_						:     int							     =  self.fwd_bfs.node_queue.pop(0      )
          lowercase_						:     List[str]							     =  self.bwd_bfs.node_queue.pop(0      )

          if current_bwd_node.pos == current_fwd_node.pos:
             lowercase_						:     List[Any]							     =  True
             return self.retrace_bidirectional_path(
                 a	,  a      )

          lowercase_						:     Tuple							     =  current_bwd_node
          lowercase_						:     Dict							     =  current_fwd_node

          lowercase_						:     Any							     =  {
              self.fwd_bfs: self.fwd_bfs.get_successors(a      ),
              self.bwd_bfs: self.bwd_bfs.get_successors(a      ),
          }

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

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





    def 					lowerCAmelCase__					(      self	:							str	,  a	:							Node	,  a	:							Node      ):






       '''simple docstring'''






       lowercase_						:     Optional[Any]							     =  self.fwd_bfs.retrace_path(a      )
       lowercase_						:     List[Any]							     =  self.bwd_bfs.retrace_path(a      )
       bwd_path.pop()
       bwd_path.reverse()
       lowercase_						:     List[Any]							     =  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)












'''simple docstring'''
import flax.linen as nn
import jax
import jax.numpy as jnp


class 							_UpperCAmelCase    (		nn.Module      ):
    __lowerCamelCase: int
    __lowerCamelCase: jnp.dtype									=     jnp.floataa




    def 					lowerCAmelCase__					(      self	:							Optional[Any]      ):






       '''simple docstring'''






       lowercase_						:     List[Any]							     =  nn.Conv(
           self.out_channels	,  kernel_size=(3, 3)	,  strides=(1, 1)	,  padding=((1, 1), (1, 1))	,  dtype=self.dtype	,  )





    def __call__(      self	:							List[str]	,  a	:							Optional[int]      ):






       '''simple docstring'''






       lowercase_     ,		lowercase_     ,		lowercase_     ,		lowercase_						:     Optional[Any]							     =  hidden_states.shape
       lowercase_						:     Tuple							     =  jax.image.resize(
           a	,  shape=(batch, height * 2, width * 2, channels)	,  method="nearest"	,  )
       lowercase_						:     List[Any]							     =  self.conv(a      )
       return hidden_states


class 							_UpperCAmelCase    (		nn.Module      ):
    __lowerCamelCase: int
    __lowerCamelCase: jnp.dtype									=     jnp.floataa




    def 					lowerCAmelCase__					(      self	:							Optional[Any]      ):






       '''simple docstring'''






       lowercase_						:     Any							     =  nn.Conv(
           self.out_channels	,  kernel_size=(3, 3)	,  strides=(2, 2)	,  padding=((1, 1), (1, 1))	,  dtype=self.dtype	,  )





    def __call__(      self	:							Any	,  a	:							int      ):






       '''simple docstring'''






       lowercase_						:     Any							     =  self.conv(a      )
       return hidden_states


class 							_UpperCAmelCase    (		nn.Module      ):
    __lowerCamelCase: int
    __lowerCamelCase: int									=     None
    __lowerCamelCase: float									=     0.0
    __lowerCamelCase: bool									=     None
    __lowerCamelCase: jnp.dtype									=     jnp.floataa




    def 					lowerCAmelCase__					(      self	:							Optional[int]      ):






       '''simple docstring'''






       lowercase_						:     Union[str, Any]							     =  self.in_channels if self.out_channels is None else self.out_channels

       lowercase_						:     Optional[int]							     =  nn.GroupNorm(num_groups=3_2	,  epsilon=1e-5      )
       lowercase_						:     Tuple							     =  nn.Conv(
           a	,  kernel_size=(3, 3)	,  strides=(1, 1)	,  padding=((1, 1), (1, 1))	,  dtype=self.dtype	,  )

       lowercase_						:     List[str]							     =  nn.Dense(a	,  dtype=self.dtype      )

       lowercase_						:     Optional[int]							     =  nn.GroupNorm(num_groups=3_2	,  epsilon=1e-5      )
       lowercase_						:     Any							     =  nn.Dropout(self.dropout_prob      )
       lowercase_						:     Dict							     =  nn.Conv(
           a	,  kernel_size=(3, 3)	,  strides=(1, 1)	,  padding=((1, 1), (1, 1))	,  dtype=self.dtype	,  )

       lowercase_						:     Tuple							     =  self.in_channels != out_channels if self.use_nin_shortcut is None else self.use_nin_shortcut

       lowercase_						:     Optional[Any]							     =  None
       if use_nin_shortcut:
          lowercase_						:     Union[str, Any]							     =  nn.Conv(
              a	,  kernel_size=(1, 1)	,  strides=(1, 1)	,  padding="VALID"	,  dtype=self.dtype	,  )





    def __call__(      self	:							List[str]	,  a	:							str	,  a	:							Dict	,  a	:							List[str]=True      ):






       '''simple docstring'''






       lowercase_						:     Dict							     =  hidden_states
       lowercase_						:     int							     =  self.norma(a      )
       lowercase_						:     List[Any]							     =  nn.swish(a      )
       lowercase_						:     Dict							     =  self.conva(a      )

       lowercase_						:     Optional[int]							     =  self.time_emb_proj(nn.swish(a      )      )
       lowercase_						:     Tuple							     =  jnp.expand_dims(jnp.expand_dims(a	,  1      )	,  1      )
       lowercase_						:     List[str]							     =  hidden_states + temb

       lowercase_						:     Optional[Any]							     =  self.norma(a      )
       lowercase_						:     Any							     =  nn.swish(a      )
       lowercase_						:     List[str]							     =  self.dropout(a	,  a      )
       lowercase_						:     int							     =  self.conva(a      )

       if self.conv_shortcut is not None:
          lowercase_						:     List[str]							     =  self.conv_shortcut(a      )

       return hidden_states + residual




