


"""simple docstring"""



from math import factorial

__snake_case         =					{str(digit): factorial(digit) for digit in range(10)}







def 						__lowerCAmelCase		(		lowercase						:						int				)			->		int:


    """simple docstring"""





    if not isinstance(lowercase		,							lowercase				):
        raise TypeError("Parameter number must be int"				)

    if number < 0:
        raise ValueError("Parameter number must be greater than or equal to 0"				)

    # Converts number in string to iterate on its digits and adds its factorial.
    return sum(DIGIT_FACTORIAL[digit] for digit in str(lowercase				)				)







def 						__lowerCAmelCase		(		lowercase						:						int = 60		,							lowercase						:						int = 100_0000				)			->		int:


    """simple docstring"""





    if not isinstance(lowercase		,							lowercase				) or not isinstance(lowercase		,							lowercase				):
        raise TypeError("Parameters chain_length and number_limit must be int"				)

    if chain_length <= 0 or number_limit <= 0:
        raise ValueError(
            "Parameters chain_length and number_limit must be greater than 0"				)

    # the counter for the chains with the exact desired length
    snake_case					:   Any         =					0
    # the cached sizes of the previous chains
    snake_case					:   dict[int, int]         =					{}

    for start_chain_element in range(1		,							lowercase				):
        # The temporary set will contain the elements of the chain
        snake_case					:   Tuple         =					set()
        snake_case					:   Optional[Any]         =					0

        # Stop computing the chain when you find a cached size, a repeating item or the
        # length is greater then the desired one.
        snake_case					:   Any         =					start_chain_element
        while (
            chain_element not in chain_sets_lengths
            and chain_element not in chain_set
            and chain_set_length <= chain_length
        ):
            chain_set.add(lowercase				)
            chain_set_length += 1
            snake_case					:   List[Any]         =					digit_factorial_sum(lowercase				)

        if chain_element in chain_sets_lengths:
            chain_set_length += chain_sets_lengths[chain_element]

        snake_case					:   Optional[int]         =					chain_set_length

        # If chain contains the exact amount of elements increase the counter
        if chain_set_length == chain_length:
            chains_counter += 1

    return chains_counter


if __name__ == "__main__":
  import doctest

  doctest.testmod()
  print(F'''{solution()}''')









"""simple docstring"""



# this script reports modified .py files under the desired list of top-level sub-dirs passed as a list of arguments, e.g.:
#   python ./utils/get_modified_files.py utils src tests examples
#
# it uses git to find the forking point and which files were modified - i.e. files not under git won't be considered
# since the output of this script is fed into Makefile commands it doesn't print a newline after the results

import re
import subprocess
import sys


__snake_case         =					subprocess.check_output("""git merge-base main HEAD""".split()).decode("""utf-8""")
__snake_case         =					(
    subprocess.check_output(F'''git diff --diff-filter=d --name-only {fork_point_sha}'''.split()).decode("""utf-8""").split()
)

__snake_case         =					"""|""".join(sys.argv[1:])
__snake_case         =					re.compile(RF'''^({joined_dirs}).*?\.py$''')

__snake_case         =					[x for x in modified_files if regex.match(x)]
print(""" """.join(relevant_modified_files), end="""""")





