





'''simple docstring'''


_SCREAMING_SNAKE_CASE		       =							2_56
# Modulus to hash a string
_SCREAMING_SNAKE_CASE		       =							1_00_00_03


def 		__a(SCREAMING_SNAKE_CASE_     :    Any						,				SCREAMING_SNAKE_CASE_     :    Optional[int]			):



    '''simple docstring'''





    _lowerCAmelCase			=					len(snake_case__			)
    _lowerCAmelCase			=					len(snake_case__			)
    if p_len > t_len:
        return False

    _lowerCAmelCase			=					0
    _lowerCAmelCase			=					0
    _lowerCAmelCase			=					1

    # Calculating the hash of pattern and substring of text
    for i in range(snake_case__			):
        _lowerCAmelCase			=					(ord(pattern[i]			) + p_hash * alphabet_size) % modulus
        _lowerCAmelCase			=					(ord(text[i]			) + text_hash * alphabet_size) % modulus
        if i == p_len - 1:
            continue
        _lowerCAmelCase			=					(modulus_power * alphabet_size) % modulus

    for i in range(0						,				t_len - p_len + 1			):
        if text_hash == p_hash and text[i : i + p_len] == pattern:
            return True
        if i == t_len - p_len:
            continue
        # Calculate the https://en.wikipedia.org/wiki/Rolling_hash
        _lowerCAmelCase			=					(
            (text_hash - ord(text[i]			) * modulus_power) * alphabet_size
            + ord(text[i + p_len]			)
        ) % modulus
    return False


def 		__a():



    '''simple docstring'''





    _lowerCAmelCase			=					"abc1abc12"
    _lowerCAmelCase			=					"alskfjaldsabc1abc1abc12k23adsfabcabc"
    _lowerCAmelCase			=					"alskfjaldsk23adsfabcabc"
    assert rabin_karp(snake_case__						,				snake_case__			) and not rabin_karp(snake_case__						,				snake_case__			)

    # Test 2)
    _lowerCAmelCase			=					"ABABX"
    _lowerCAmelCase			=					"ABABZABABYABABX"
    assert rabin_karp(snake_case__						,				snake_case__			)

    # Test 3)
    _lowerCAmelCase			=					"AAAB"
    _lowerCAmelCase			=					"ABAAAAAB"
    assert rabin_karp(snake_case__						,				snake_case__			)

    # Test 4)
    _lowerCAmelCase			=					"abcdabcy"
    _lowerCAmelCase			=					"abcxabcdabxabcdabcdabcy"
    assert rabin_karp(snake_case__						,				snake_case__			)

    # Test 5)
    _lowerCAmelCase			=					"Lü"
    _lowerCAmelCase			=					"Lüsai"
    assert rabin_karp(snake_case__						,				snake_case__			)
    _lowerCAmelCase			=					"Lue"
    assert not rabin_karp(snake_case__						,				snake_case__			)
    print("Success."			)


if __name__ == "__main__":
       test_rabin_karp()








"""simple docstring"""




from typing import Any



def     a__ (				snake_case__       , snake_case__       , snake_case__       , snake_case__       , snake_case__       , )						->					list:
			_validation(
			    snake_case__       , snake_case__       , snake_case__       , snake_case__       , snake_case__       , )
			# Creates data structures and fill initial step
			lowerCamelCase			      =					{}
			lowerCamelCase			      =					{}
			for state in states_space:
						lowerCamelCase			      =					observations_space[0]
						lowerCamelCase			      =					(
						    initial_probabilities[state] * emission_probabilities[state][observation]
						)
						lowerCamelCase			      =					None

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

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

									lowerCamelCase			      =					arg_max

    # The final observation
			lowerCamelCase			      =					observations_space[len(snake_case__				) - 1]

			# argmax for given final observation
			lowerCamelCase			      =					""""""
			lowerCamelCase			      =					-1
			for k_state in states_space:
						lowerCamelCase			      =					probabilities[(k_state, final_observation)]
						if probability > max_probability:
									lowerCamelCase			      =					probability
									lowerCamelCase			      =					k_state
			lowerCamelCase			      =					arg_max

			# Process pointers backwards
			lowerCamelCase			      =					last_state
			lowerCamelCase			      =					[]
			for o in range(len(snake_case__				) - 1       , -1       , -1				):
						result.append(snake_case__				)
						lowerCamelCase			      =					pointers[previous, observations_space[o]]
			result.reverse()

			return result



def     a__ (				snake_case__       , snake_case__       , snake_case__       , snake_case__       , snake_case__       , )						->					None:
			_validate_not_empty(
			    snake_case__       , snake_case__       , snake_case__       , snake_case__       , snake_case__       , )
			_validate_lists(snake_case__       , snake_case__				)
			_validate_dicts(
			    snake_case__       , snake_case__       , snake_case__				)



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



def     a__ (				snake_case__       , snake_case__				)						->					None:
			_validate_list(snake_case__       , """observations_space"""				)
			_validate_list(snake_case__       , """states_space"""				)



def     a__ (				snake_case__       , snake_case__				)						->					None:
			if not isinstance(_object       , snake_case__				):
						lowerCamelCase			      =					F'{var_name} must be a list'
						raise ValueError(snake_case__				)
			else:
						for x in _object:
									if not isinstance(snake_case__       , snake_case__				):
												lowerCamelCase			      =					F'{var_name} must be a list of strings'
												raise ValueError(snake_case__				)



def     a__ (				snake_case__       , snake_case__       , snake_case__       , )						->					None:
			_validate_dict(snake_case__       , """initial_probabilities"""       , snake_case__				)
			_validate_nested_dict(snake_case__       , """transition_probabilities"""				)
			_validate_nested_dict(snake_case__       , """emission_probabilities"""				)



def     a__ (				snake_case__       , snake_case__				)						->					None:
			_validate_dict(_object       , snake_case__       , snake_case__				)
			for x in _object.values():
						_validate_dict(snake_case__       , snake_case__       , snake_case__       , snake_case__				)



def     a__ (				snake_case__       , snake_case__       , snake_case__       , snake_case__ = False				)						->					None:
			if not isinstance(_object       , snake_case__				):
						lowerCamelCase			      =					F'{var_name} must be a dict'
						raise ValueError(snake_case__				)
			if not all(isinstance(snake_case__       , snake_case__				) for x in _object				):
						lowerCamelCase			      =					F'{var_name} all keys must be strings'
						raise ValueError(snake_case__				)
			if not all(isinstance(snake_case__       , snake_case__				) for x in _object.values()				):
						lowerCamelCase			      =					"""nested dictionary """ if nested else """"""
						lowerCamelCase			      =					F'{var_name} {nested_text}all values must be {value_type.__name__}'
						raise ValueError(snake_case__				)


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

					testmod()



