from math import pow





def 		__lowerCamelCase							(UpperCAmelCase__       :							int ,	UpperCAmelCase__       :							int ,	UpperCAmelCase__       :							int ,	UpperCAmelCase__       :							int ,	UpperCAmelCase__       :							int ,	):
					if current_sum == needed_sum:
										# If the sum of the powers is equal to needed_sum, then we have a solution.
										solutions_count += 1
										return current_sum, solutions_count

					SCREAMING_SNAKE_CASE           =    int(pow(UpperCAmelCase__ ,	UpperCAmelCase__					)					)
					if current_sum + i_to_n <= needed_sum:
										# If the sum of the powers is less than needed_sum, then continue adding powers.
										current_sum += i_to_n
										SCREAMING_SNAKE_CASE     ,				SCREAMING_SNAKE_CASE           =    backtrack(
										    UpperCAmelCase__ ,	UpperCAmelCase__ ,	current_number + 1 ,	UpperCAmelCase__ ,	UpperCAmelCase__					)
										current_sum -= i_to_n
					if i_to_n < needed_sum:
										# If the power of i is less than needed_sum, then try with the next power.
										SCREAMING_SNAKE_CASE     ,				SCREAMING_SNAKE_CASE           =    backtrack(
										    UpperCAmelCase__ ,	UpperCAmelCase__ ,	current_number + 1 ,	UpperCAmelCase__ ,	UpperCAmelCase__					)
					return current_sum, solutions_count





def 		__lowerCamelCase							(UpperCAmelCase__       :							int ,	UpperCAmelCase__       :							int					):
					if not (1 <= needed_sum <= 1_0_0_0 and 2 <= power <= 1_0):
										raise ValueError(
										    "Invalid input\n"
										    "needed_sum must be between 1 and 1000, power between 2 and 10."					)

					return backtrack(UpperCAmelCase__ ,	UpperCAmelCase__ ,	1 ,	0 ,	0					)[1]  # Return the solutions_count


if __name__ == "__main__":
							import doctest

							doctest.testmod()





import contextlib
from multiprocessing import Pool, RLock

from tqdm.auto import tqdm

from ..utils import experimental, logging


_lowerCamelCase   :				Union[str, Any]     			=						logging.get_logger(__name__)


class   lowercase      :
							lowercase__  :    str									=							None





@experimental
def 		__lowerCamelCase							(UpperCAmelCase__       :							Any ,	UpperCAmelCase__       :							int ,	UpperCAmelCase__       :							Optional[int] ,	UpperCAmelCase__       :							List[Any] ,	UpperCAmelCase__       :							Union[str, Any] ,	UpperCAmelCase__       :							List[str] ,	UpperCAmelCase__       :							Any					):
					if ParallelBackendConfig.backend_name is None:
										return _map_with_multiprocessing_pool(
										    UpperCAmelCase__ ,	UpperCAmelCase__ ,	UpperCAmelCase__ ,	UpperCAmelCase__ ,	UpperCAmelCase__ ,	UpperCAmelCase__ ,	UpperCAmelCase__					)

					return _map_with_joblib(UpperCAmelCase__ ,	UpperCAmelCase__ ,	UpperCAmelCase__ ,	UpperCAmelCase__ ,	UpperCAmelCase__ ,	UpperCAmelCase__ ,	UpperCAmelCase__					)





def 		__lowerCamelCase							(UpperCAmelCase__       :							Optional[Any] ,	UpperCAmelCase__       :							List[Any] ,	UpperCAmelCase__       :							int ,	UpperCAmelCase__       :							Union[str, Any] ,	UpperCAmelCase__       :							Any ,	UpperCAmelCase__       :							int ,	UpperCAmelCase__       :							Optional[Any]					):
					SCREAMING_SNAKE_CASE           =    num_proc if num_proc <= len(UpperCAmelCase__					) else len(UpperCAmelCase__					)
					SCREAMING_SNAKE_CASE           =    []  # We organize the splits ourselve (contiguous splits)
					for index in range(UpperCAmelCase__					):
										SCREAMING_SNAKE_CASE           =    len(UpperCAmelCase__					) // num_proc
										SCREAMING_SNAKE_CASE           =    len(UpperCAmelCase__					) % num_proc
										SCREAMING_SNAKE_CASE           =    div * index + min(UpperCAmelCase__ ,	UpperCAmelCase__					)
										SCREAMING_SNAKE_CASE           =    start + div + (1 if index < mod else 0)
										split_kwds.append((function, iterable[start:end], types, index, disable_tqdm, desc)					)

					if len(UpperCAmelCase__					) != sum(len(i[1]					) for i in split_kwds					):
										raise ValueError(
										    F"Error dividing inputs iterable among processes. "
										    F"Total number of objects {len(UpperCAmelCase__					)}, "
										    F"length: {sum(len(i[1]					) for i in split_kwds					)}"					)

					logger.info(
					    F"Spawning {num_proc} processes for {len(UpperCAmelCase__					)} objects in slices of {[len(i[1]					) for i in split_kwds]}"					)
					SCREAMING_SNAKE_CASE     ,				SCREAMING_SNAKE_CASE           =    None, None
					if not disable_tqdm:
										SCREAMING_SNAKE_CASE     ,				SCREAMING_SNAKE_CASE           =    (RLock(),), tqdm.set_lock
					with Pool(UpperCAmelCase__ ,	initargs=UpperCAmelCase__ ,	initializer=UpperCAmelCase__					) as pool:
										SCREAMING_SNAKE_CASE           =    pool.map(UpperCAmelCase__ ,	UpperCAmelCase__					)
					logger.info(F"Finished {num_proc} processes"					)
					SCREAMING_SNAKE_CASE           =    [obj for proc_res in mapped for obj in proc_res]
					logger.info(F"Unpacked {len(UpperCAmelCase__					)} objects"					)

					return mapped





def 		__lowerCamelCase							(UpperCAmelCase__       :							Tuple ,	UpperCAmelCase__       :							Dict ,	UpperCAmelCase__       :							Any ,	UpperCAmelCase__       :							Optional[int] ,	UpperCAmelCase__       :							Tuple ,	UpperCAmelCase__       :							Tuple ,	UpperCAmelCase__       :							Any					):
					# progress bar is not yet supported for _map_with_joblib, because tqdm couldn't accurately be applied to joblib,
					# and it requires monkey-patching joblib internal classes which is subject to change
					import joblib

					with joblib.parallel_backend(ParallelBackendConfig.backend_name ,	n_jobs=UpperCAmelCase__					):
										return joblib.Parallel()(
										    joblib.delayed(UpperCAmelCase__					)((function, obj, types, None, True, None)					) for obj in iterable					)





@experimental
@contextlib.contextmanager
def 		__lowerCamelCase							(UpperCAmelCase__       :							str					):
					SCREAMING_SNAKE_CASE           =    backend_name

					if backend_name == "spark":
										from joblibspark import register_spark

										register_spark()

										# TODO: call create_cache_and_write_probe if "download" in steps
										# TODO: raise NotImplementedError when Dataset.map etc is called

					try:
										yield
					finally:
										SCREAMING_SNAKE_CASE           =    None




