






'''simple docstring'''







# flake8: noqa
# Lint as: python3

from typing import Dict, List, Optional, Type

from .. import config
from ..utils import logging
from .formatting import (
    ArrowFormatter,
    CustomFormatter,
    Formatter,
    PandasFormatter,
    PythonFormatter,
    TensorFormatter,
    format_table,
    query_table,
)
from .np_formatter import NumpyFormatter


UpperCamelCase    :      str  			=		logging.get_logger(__name__)

UpperCamelCase    :      Union[str, Any]  			=		{}
UpperCamelCase    :      Dict  			=		{}
UpperCamelCase    :      Any  			=		{}
def 						A__			(				__lowerCAmelCase		:			Any   ,    __lowerCAmelCase		:			str   ,    __lowerCAmelCase		:			List[Any] = None   ,    ):
						lowerCamelCase__         =  aliases if aliases is not None else []
						if format_type in _FORMAT_TYPES:
												logger.warning(
												    F'''Overwriting format type \'{format_type}\' ({_FORMAT_TYPES[format_type].__name__} -> {formatter_cls.__name__})'''						)
						lowerCamelCase__         =  formatter_cls
						for alias in set(aliases + [format_type]						):
												if alias in _FORMAT_TYPES_ALIASES:
																		logger.warning(
																		    F'''Overwriting format type alias \'{alias}\' ({_FORMAT_TYPES_ALIASES[alias]} -> {format_type})'''						)
												lowerCamelCase__         =  format_type
def 						A__			(				__lowerCAmelCase		:			Optional[Any]   ,    __lowerCAmelCase		:			List[str]   ,    __lowerCAmelCase		:			Tuple = None						):
						lowerCamelCase__         =  aliases if aliases is not None else []
						for alias in set(aliases + [format_type]						):
												lowerCamelCase__         =  unavailable_error


# Here we define all the available formatting functions that can be used by `Dataset.set_format`
_register_formatter(PythonFormatter, None, aliases=['python'])
_register_formatter(ArrowFormatter, 'arrow', aliases=['pa', 'pyarrow'])
_register_formatter(NumpyFormatter, 'numpy', aliases=['np'])
_register_formatter(PandasFormatter, 'pandas', aliases=['pd'])
_register_formatter(CustomFormatter, 'custom')

if config.TORCH_AVAILABLE:
							from .torch_formatter import TorchFormatter

							_register_formatter(TorchFormatter, 'torch', aliases=['pt', 'pytorch'])
else:
							UpperCamelCase    :      List[Any]  			=		ValueError('PyTorch needs to be installed to be able to return PyTorch tensors.')
							_register_unavailable_formatter(_torch_error, 'torch', aliases=['pt', 'pytorch'])

if config.TF_AVAILABLE:
							from .tf_formatter import TFFormatter

							_register_formatter(TFFormatter, 'tensorflow', aliases=['tf'])
else:
							UpperCamelCase    :      int  			=		ValueError('Tensorflow needs to be installed to be able to return Tensorflow tensors.')
							_register_unavailable_formatter(_tf_error, 'tensorflow', aliases=['tf'])

if config.JAX_AVAILABLE:
							from .jax_formatter import JaxFormatter

							_register_formatter(JaxFormatter, 'jax', aliases=[])
else:
							UpperCamelCase    :      Optional[Any]  			=		ValueError('JAX needs to be installed to be able to return JAX arrays.')
							_register_unavailable_formatter(_jax_error, 'jax', aliases=[])
def 						A__			(				__lowerCAmelCase		:			Union[str, Any]						):







						if format_type in _FORMAT_TYPES_ALIASES:
												return _FORMAT_TYPES_ALIASES[format_type]
						else:
												return format_type





def 						A__			(				__lowerCAmelCase		:			Union[str, Any]   ,    **__lowerCAmelCase		:			Tuple						):
						lowerCamelCase__         =  get_format_type_from_alias(__snake_case						)
						if format_type in _FORMAT_TYPES:
												return _FORMAT_TYPES[format_type](**__snake_case						)
						if format_type in _FORMAT_TYPES_ALIASES_UNAVAILABLE:
												raise _FORMAT_TYPES_ALIASES_UNAVAILABLE[format_type]
						else:
												raise ValueError(
												    F'''Return type should be None or selected in {list(type for type in _FORMAT_TYPES.keys() if type != None						)}, but got \'{format_type}\''''						)









'''simple docstring'''







from math import factorial

UpperCamelCase    :      dict[str, int]  			=		{str(digit): factorial(digit) for digit in range(10)}
def 						A__			(				__lowerCAmelCase		:			int						):
						if not isinstance(__lowerCAmelCase   ,    __lowerCAmelCase						):
												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(__lowerCAmelCase						)						)
def 						A__			(				__lowerCAmelCase		:			int = 60   ,    __lowerCAmelCase		:			int = 100_0000						):

						if not isinstance(__lowerCAmelCase   ,    __lowerCAmelCase						) or not isinstance(__lowerCAmelCase   ,    __lowerCAmelCase						):
												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
						lowerCamelCase__         =  0
						# the cached sizes of the previous chains
						lowerCamelCase__         =  {}

						for start_chain_element in range(1   ,    __lowerCAmelCase						):
												# The temporary set will contain the elements of the chain
												lowerCamelCase__         =  set()
												lowerCamelCase__         =  0

												# Stop computing the chain when you find a cached size, a repeating item or the
												# length is greater then the desired one.
												lowerCamelCase__         =  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(__lowerCAmelCase						)
																		chain_set_length += 1
																		lowerCamelCase__         =  digit_factorial_sum(__lowerCAmelCase						)

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

												lowerCamelCase__         =  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()}')

