

class        a__       :







  """simple docstring"""




  def __init__(			self    : Union[str, Any]		)					->Any:
        """simple docstring"""







        SCREAMING_SNAKE_CASE :      Tuple       =   """"""
        SCREAMING_SNAKE_CASE :      Dict       =   """"""
        SCREAMING_SNAKE_CASE :      List[Any]       =   []


  def  _lowercase      (			self    : List[str]				,				UpperCAmelCase__    : int				,				UpperCAmelCase__    : int		)					->int:
        """simple docstring"""







        if m == -1:
              return n + 1
        elif n == -1:
              return m + 1
        elif self.dp[m][n] > -1:
              return self.dp[m][n]
        else:
              if self.worda[m] == self.worda[n]:
                    SCREAMING_SNAKE_CASE :      List[str]       =   self.__min_dist_top_down_dp(m - 1				,				n - 1		)
              else:
                    SCREAMING_SNAKE_CASE :      List[Any]       =   self.__min_dist_top_down_dp(UpperCAmelCase__				,				n - 1		)
                    SCREAMING_SNAKE_CASE :      List[Any]       =   self.__min_dist_top_down_dp(m - 1				,				UpperCAmelCase__		)
                    SCREAMING_SNAKE_CASE :      List[str]       =   self.__min_dist_top_down_dp(m - 1				,				n - 1		)
                    SCREAMING_SNAKE_CASE :      List[Any]       =   1 + min(UpperCAmelCase__				,				UpperCAmelCase__				,				UpperCAmelCase__		)

              return self.dp[m][n]


  def  _lowercase      (			self    : Tuple				,				UpperCAmelCase__    : str				,				UpperCAmelCase__    : str		)					->int:
        """simple docstring"""







        SCREAMING_SNAKE_CASE :      List[Any]       =   worda
        SCREAMING_SNAKE_CASE :      int       =   worda
        SCREAMING_SNAKE_CASE :      str       =   [[-1 for _ in range(len(UpperCAmelCase__		)		)] for _ in range(len(UpperCAmelCase__		)		)]

        return self.__min_dist_top_down_dp(len(UpperCAmelCase__		) - 1				,				len(UpperCAmelCase__		) - 1		)




  def  _lowercase      (			self    : str				,				UpperCAmelCase__    : str				,				UpperCAmelCase__    : str		)					->int:
        """simple docstring"""







        SCREAMING_SNAKE_CASE :      Tuple       =   worda
        SCREAMING_SNAKE_CASE :      Dict       =   worda
        SCREAMING_SNAKE_CASE :      Union[str, Any]       =   len(UpperCAmelCase__		)
        SCREAMING_SNAKE_CASE :      Tuple       =   len(UpperCAmelCase__		)
        SCREAMING_SNAKE_CASE :      Any       =   [[0 for _ in range(n + 1		)] for _ in range(m + 1		)]

        for i in range(m + 1		):
              for j in range(n + 1		):
                    if i == 0:  # first string is empty
                          SCREAMING_SNAKE_CASE :      List[Any]       =   j
                    elif j == 0:  # second string is empty
                          SCREAMING_SNAKE_CASE :      Optional[int]       =   i
                    elif worda[i - 1] == worda[j - 1]:  # last characters are equal
                          SCREAMING_SNAKE_CASE :      List[Any]       =   self.dp[i - 1][j - 1]
                    else:
                          SCREAMING_SNAKE_CASE :      Dict       =   self.dp[i][j - 1]
                          SCREAMING_SNAKE_CASE :      Union[str, Any]       =   self.dp[i - 1][j]
                          SCREAMING_SNAKE_CASE :      List[str]       =   self.dp[i - 1][j - 1]
                          SCREAMING_SNAKE_CASE :      Union[str, Any]       =   1 + min(UpperCAmelCase__				,				UpperCAmelCase__				,				UpperCAmelCase__		)
        return self.dp[m][n]


if __name__ == "__main__":
  UpperCAmelCase__ :     str				    =    EditDistance()

  print("""****************** Testing Edit Distance DP Algorithm ******************""")
  print()

  UpperCAmelCase__ :     str				    =    input("""Enter the first string: """).strip()
  UpperCAmelCase__ :     str				    =    input("""Enter the second string: """).strip()

  print()
  print(F"""The minimum edit distance is: {solver.min_dist_top_down(Sa, Sa)}""")
  print(F"""The minimum edit distance is: {solver.min_dist_bottom_up(Sa, Sa)}""")
  print()
  print("""*************** End of Testing Edit Distance DP Algorithm ***************""")







from __future__ import annotations

import numpy as np






def 					__lowercase      (     _A			)     ->						tuple[np.ndarray, np.ndarray]:
      SCREAMING_SNAKE_CASE     ,	SCREAMING_SNAKE_CASE :      Dict       =   np.shape(_A			)
      if rows != columns:
            SCREAMING_SNAKE_CASE :      int       =   (
                """'table' has to be of square shaped array but got a """
                F"{rows}x{columns} array:\n{table}"
            )
            raise ValueError(_A			)

      SCREAMING_SNAKE_CASE :      Union[str, Any]       =   np.zeros((rows, columns)			)
      SCREAMING_SNAKE_CASE :      Optional[Any]       =   np.zeros((rows, columns)			)
      for i in range(_A			):
            for j in range(_A			):
                  SCREAMING_SNAKE_CASE :      Tuple       =   sum(lower[i][k] * upper[k][j] for k in range(_A			)			)
                  if upper[j][j] == 0:
                        raise ArithmeticError("""No LU decomposition exists"""			)
                  SCREAMING_SNAKE_CASE :      Union[str, Any]       =   (table[i][j] - total) / upper[j][j]
            SCREAMING_SNAKE_CASE :      Optional[Any]       =   1
            for j in range(_A						,    _A			):
                  SCREAMING_SNAKE_CASE :      List[str]       =   sum(lower[i][k] * upper[k][j] for k in range(_A			)			)
                  SCREAMING_SNAKE_CASE :      Optional[Any]       =   table[i][j] - total
      return lower, upper


if __name__ == "__main__":
  import doctest

  doctest.testmod()




