
from __future__ import annotations

import matplotlib.pyplot as plt  # type: ignore
import numpy

# initial triangle of Koch snowflake
lowerCamelCase__    :		Optional[int]          =   numpy.array([0, 0])
lowerCamelCase__    :		int          =   numpy.array([0.5, 0.8_660_254])
lowerCamelCase__    :		str          =   numpy.array([1, 0])
lowerCamelCase__    :		Dict          =   [VECTOR_1, VECTOR_2, VECTOR_3, VECTOR_1]

def 		UpperCamelCase	(      lowercase_ , lowercase_   ):


  '''simple docstring'''






  lowercase__  :   Dict    		=      initial_vectors
  for _ in range(lowercase_   ):
    lowercase__  :   Union[str, Any]    		=      iteration_step(lowercase_   )
  return vectors

def 		UpperCamelCase	(      lowercase_   ):


  '''simple docstring'''






  lowercase__  :   str    		=      []
  for i, start_vector in enumerate(vectors[:-1]   ):
    lowercase__  :   List[Any]    		=      vectors[i + 1]
    new_vectors.append(lowercase_   )
    lowercase__  :   Optional[Any]    		=      end_vector - start_vector
    new_vectors.append(start_vector + difference_vector / 3   )
    new_vectors.append(
        start_vector + difference_vector / 3 + rotate(difference_vector / 3 , 60   )   )
    new_vectors.append(start_vector + difference_vector * 2 / 3   )
  new_vectors.append(vectors[-1]   )
  return new_vectors

def 		UpperCamelCase	(      lowercase_ , lowercase_   ):


  '''simple docstring'''






  lowercase__  :   str    		=      numpy.radians(lowercase_   )
  lowercase__  :   Tuple    		=      numpy.cos(lowercase_   ), numpy.sin(lowercase_   )
  lowercase__  :   Union[str, Any]    		=      numpy.array(((c, -s), (s, c))   )
  return numpy.dot(lowercase_ , lowercase_   )

def 		UpperCamelCase	(      lowercase_   ):


  '''simple docstring'''






  lowercase__  :   str    		=      plt.gca()
  axes.set_aspect("""equal"""   )

  # matplotlib.pyplot.plot takes a list of all x-coordinates and a list of all
  # y-coordinates as inputs, which are constructed from the vector-list using
  # zip()
  lowercase__  :   Optional[Any]    		=      zip(*lowercase_   )
  plt.plot(lowercase_ , lowercase_   )
  plt.show()


if __name__ == "__main__":
     import doctest

     doctest.testmod()

     lowerCamelCase__    :		Optional[Any]          =   iterate(INITIAL_VECTORS, 5)
     plot(processed_vectors)








from math import factorial

lowerCamelCase__    :		dict[str, int]          =   {str(digit): factorial(digit) for digit in range(1_0)}

def 		UpperCamelCase	(      lowercase_   )		->	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 		UpperCamelCase	(      lowercase_ = 60 , lowercase_ = 1_00_00_00   )		->	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
  lowercase__  :   List[Any]    		=      0
  # the cached sizes of the previous chains
  lowercase__  :   dict[int, int]    		=      {}

  for start_chain_element in range(1 , lowercase_   ):
    # The temporary set will contain the elements of the chain
    lowercase__  :   Optional[Any]    		=      set()
    lowercase__  :   Union[str, Any]    		=      0

    # Stop computing the chain when you find a cached size, a repeating item or the
    # length is greater then the desired one.
    lowercase__  :   Union[str, 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
      lowercase__  :   str    		=      digit_factorial_sum(lowercase_   )

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

    lowercase__  :   str    		=      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()}''')






