
from typing import Any







def 						_snake_case(  SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     )			->   list:
       _validation(
           SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     )
       # Creates data structures and fill initial step
       lowercase							:					dict	     =				{}
       lowercase							:					dict	     =				{}
       for state in states_space:
              lowercase							:					List[Any]	     =				observations_space[0]
              lowercase							:					Dict	     =				(
                  initial_probabilities[state] * emission_probabilities[state][observation]
              )
              lowercase							:					List[Any]	     =				None

       # Fills the data structure with the probabilities of
       # different transitions and pointers to previous states
       for o in range(1 ,     len(SCREAMING_SNAKE_CASE__    )    ):
              lowercase							:					Union[str, Any]	     =				observations_space[o]
              lowercase							:					Optional[Any]	     =				observations_space[o - 1]
              for state in states_space:
                     # Calculates the argmax for probability function
                     lowercase							:					Optional[Any]	     =				""""""
                     lowercase							:					str	     =				-1
                     for k_state in states_space:
                            lowercase							:					Optional[int]	     =				(
                                probabilities[(k_state, prior_observation)]
                                * transition_probabilities[k_state][state]
                                * emission_probabilities[state][observation]
                            )
                            if probability > max_probability:
                                   lowercase							:					Union[str, Any]	     =				probability
                                   lowercase							:					Optional[int]	     =				k_state

            # Update probabilities and pointers dicts
                     lowercase							:					int	     =				(
                         probabilities[(arg_max, prior_observation)]
                         * transition_probabilities[arg_max][state]
                         * emission_probabilities[state][observation]
                     )

                     lowercase							:					int	     =				arg_max

    # The final observation
       lowercase							:					List[str]	     =				observations_space[len(SCREAMING_SNAKE_CASE__    ) - 1]

       # argmax for given final observation
       lowercase							:					List[str]	     =				""""""
       lowercase							:					Any	     =				-1
       for k_state in states_space:
              lowercase							:					str	     =				probabilities[(k_state, final_observation)]
              if probability > max_probability:
                     lowercase							:					Optional[Any]	     =				probability
                     lowercase							:					Optional[int]	     =				k_state
       lowercase							:					Optional[Any]	     =				arg_max

       # Process pointers backwards
       lowercase							:					List[str]	     =				last_state
       lowercase							:					List[Any]	     =				[]
       for o in range(len(SCREAMING_SNAKE_CASE__    ) - 1 ,     -1 ,     -1    ):
              result.append(SCREAMING_SNAKE_CASE__    )
              lowercase							:					Optional[int]	     =				pointers[previous, observations_space[o]]
       result.reverse()

       return result







def 						_snake_case(  SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     )			->   None:
       _validate_not_empty(
           SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     )
       _validate_lists(SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    )
       _validate_dicts(
           SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    )







def 						_snake_case(  SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     )			->   None:
       if not all(
           [
               observations_space,
               states_space,
               initial_probabilities,
               transition_probabilities,
               emission_probabilities,
           ]    ):
              raise ValueError("""There's an empty parameter"""    )







def 						_snake_case(  SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    )			->   None:
       _validate_list(SCREAMING_SNAKE_CASE__ ,     """observations_space"""    )
       _validate_list(SCREAMING_SNAKE_CASE__ ,     """states_space"""    )







def 						_snake_case(  SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    )			->   None:
       if not isinstance(_object ,     SCREAMING_SNAKE_CASE__    ):
              lowercase							:					str	     =				f"{var_name} must be a list"
              raise ValueError(SCREAMING_SNAKE_CASE__    )
       else:
              for x in _object:
                     if not isinstance(SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    ):
                            lowercase							:					int	     =				f"{var_name} must be a list of strings"
                            raise ValueError(SCREAMING_SNAKE_CASE__    )







def 						_snake_case(  SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     )			->   None:
       _validate_dict(SCREAMING_SNAKE_CASE__ ,     """initial_probabilities""" ,     SCREAMING_SNAKE_CASE__    )
       _validate_nested_dict(SCREAMING_SNAKE_CASE__ ,     """transition_probabilities"""    )
       _validate_nested_dict(SCREAMING_SNAKE_CASE__ ,     """emission_probabilities"""    )







def 						_snake_case(  SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    )			->   None:
       _validate_dict(_object ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    )
       for x in _object.values():
              _validate_dict(SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    )







def 						_snake_case(  SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__ = False    )			->   None:
       if not isinstance(_object ,     SCREAMING_SNAKE_CASE__    ):
              lowercase							:					Optional[Any]	     =				f"{var_name} must be a dict"
              raise ValueError(SCREAMING_SNAKE_CASE__    )
       if not all(isinstance(SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    ) for x in _object    ):
              lowercase							:					List[Any]	     =				f"{var_name} all keys must be strings"
              raise ValueError(SCREAMING_SNAKE_CASE__    )
       if not all(isinstance(SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    ) for x in _object.values()    ):
              lowercase							:					Optional[Any]	     =				"""nested dictionary """ if nested else """"""
              lowercase							:					Optional[Any]	     =				f"{var_name} {nested_text}all values must be {value_type.__name__}"
              raise ValueError(SCREAMING_SNAKE_CASE__    )


if __name__ == "__main__":
  from doctest import testmod

  testmod()


from __future__ import annotations

from itertools import permutations
from random import randint
from timeit import repeat







def 						_snake_case(  )			->   tuple[list[int], int]:
       lowercase							:					List[Any]	     =				[randint(-1_000 ,     1_000    ) for i in range(10    )]
       lowercase							:					Tuple	     =				randint(-5_000 ,     5_000    )
       return (arr, r)


lowercase  : List[Any]						   =							make_dataset()







def 						_snake_case(  SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    )			->   tuple[int, ...]:
       for triplet in permutations(SCREAMING_SNAKE_CASE__ ,     3    ):
              if sum(SCREAMING_SNAKE_CASE__    ) == target:
                     return tuple(sorted(SCREAMING_SNAKE_CASE__    )    )
       return (0, 0, 0)







def 						_snake_case(  SCREAMING_SNAKE_CASE__ ,     SCREAMING_SNAKE_CASE__    )			->   tuple[int, int, int]:
       arr.sort()
       lowercase							:					Optional[int]	     =				len(SCREAMING_SNAKE_CASE__    )
       for i in range(n - 1    ):
              lowercase     ,      lowercase							:					Optional[Any]	     =				i + 1, n - 1
              while left < right:
                     if arr[i] + arr[left] + arr[right] == target:
                            return (arr[i], arr[left], arr[right])
                     elif arr[i] + arr[left] + arr[right] < target:
                            left += 1
                     elif arr[i] + arr[left] + arr[right] > target:
                            right -= 1
       return (0, 0, 0)







def 						_snake_case(  )			->   tuple[float, float]:
       lowercase							:					Dict	     =				"""
from __main__ import dataset, triplet_sum1, triplet_sum2
"""
       lowercase							:					Tuple	     =				"""
triplet_sum1(*dataset)
"""
       lowercase							:					int	     =				"""
triplet_sum2(*dataset)
"""
       lowercase							:					str	     =				repeat(setup=SCREAMING_SNAKE_CASE__ ,     stmt=SCREAMING_SNAKE_CASE__ ,     repeat=5 ,     number=10_000    )
       lowercase							:					Dict	     =				repeat(setup=SCREAMING_SNAKE_CASE__ ,     stmt=SCREAMING_SNAKE_CASE__ ,     repeat=5 ,     number=10_000    )
       return (min(SCREAMING_SNAKE_CASE__    ), min(SCREAMING_SNAKE_CASE__    ))


if __name__ == "__main__":
  from doctest import testmod

  testmod()
  lowercase  : Union[str, Any]						   =							solution_times()
  print(F'''The time for naive implementation is {times[0]}.''')
  print(F'''The time for optimized implementation is {times[1]}.''')
