
import itertools
from dataclasses import dataclass
from typing import List, Optional

import pyarrow as pa
import pyarrow.parquet as pq

import datasets
from datasets.table import table_cast


_SCREAMING_SNAKE_CASE    :      Optional[Any]          =			datasets.utils.logging.get_logger(__name__)







@dataclass
class  UpperCamelCase__		(    datasets.BuilderConfig   ):







	'''simple docstring'''
	_lowerCAmelCase							       =				10_000
	_lowerCAmelCase							       =				None
	_lowerCAmelCase							       =				None







class  UpperCamelCase__		(    datasets.ArrowBasedBuilder   ):







	'''simple docstring'''
	_lowerCAmelCase							       =				ParquetConfig





	def   __snake_case				(			self		):
					return datasets.DatasetInfo(features=self.config.features		)





	def   __snake_case				(			self				,       UpperCamelCase__		):
					if not self.config.data_files:
									raise ValueError(F"At least one data file must be specified, but got data_files={self.config.data_files}"		)
					A__  :	Tuple         =							dl_manager.download_and_extract(self.config.data_files		)
					if isinstance(UpperCamelCase__				,       (str, list, tuple)		):
									A__  :	Optional[int]         =							data_files
									if isinstance(UpperCamelCase__				,       UpperCamelCase__		):
													A__  :	List[str]         =							[files]
									# Use `dl_manager.iter_files` to skip hidden files in an extracted archive
									A__  :	Optional[int]         =							[dl_manager.iter_files(UpperCamelCase__		) for file in files]
									return [datasets.SplitGenerator(name=datasets.Split.TRAIN				,       gen_kwargs={'''files''': files}		)]
					A__  :	Dict         =							[]
					for split_name, files in data_files.items():
									if isinstance(UpperCamelCase__				,       UpperCamelCase__		):
													A__  :	Optional[Any]         =							[files]
									# Use `dl_manager.iter_files` to skip hidden files in an extracted archive
									A__  :	int         =							[dl_manager.iter_files(UpperCamelCase__		) for file in files]
									# Infer features is they are stoed in the arrow schema
									if self.info.features is None:
													for file in itertools.chain.from_iterable(UpperCamelCase__		):
																	with open(UpperCamelCase__				,       '''rb'''		) as f:
																					A__  :	List[Any]         =							datasets.Features.from_arrow_schema(pq.read_schema(UpperCamelCase__		)		)
																	break
									splits.append(datasets.SplitGenerator(name=UpperCamelCase__				,       gen_kwargs={'''files''': files}		)		)
					return splits





	def   __snake_case				(			self				,       UpperCamelCase__		):
					if self.info.features is not None:
									# more expensive cast to support nested features with keys in a different order
									# allows str <-> int/float or str to Audio for example
									A__  :	str         =							table_cast(UpperCamelCase__				,       self.info.features.arrow_schema		)
					return pa_table





	def   __snake_case				(			self				,       UpperCamelCase__		):
					A__  :	Dict         =							self.info.features.arrow_schema if self.info.features is not None else None
					if self.info.features is not None and self.config.columns is not None:
									if sorted(field.name for field in schema		) != sorted(self.config.columns		):
													raise ValueError(
													    F"Tried to load parquet data with columns '{self.config.columns}' with mismatching features '{self.info.features}'"		)
					for file_idx, file in enumerate(itertools.chain.from_iterable(UpperCamelCase__		)		):
									with open(UpperCamelCase__				,       '''rb'''		) as f:
													A__  :	Dict         =							pq.ParquetFile(UpperCamelCase__		)
													try:
																	for batch_idx, record_batch in enumerate(
																	    parquet_file.iter_batches(batch_size=self.config.batch_size				,       columns=self.config.columns		)		):
																					A__  :	Dict         =							pa.Table.from_batches([record_batch]		)
																					# Uncomment for debugging (will print the Arrow table size and elements)
																					# logger.warning(f"pa_table: {pa_table} num rows: {pa_table.num_rows}")
																					# logger.warning('\n'.join(str(pa_table.slice(i, 1).to_pydict()) for i in range(pa_table.num_rows)))
																					yield F"{file_idx}_{batch_idx}", self._cast_table(UpperCamelCase__		)
													except ValueError as e:
																	logger.error(F"Failed to read file '{file}' with error {type(UpperCamelCase__		)}: {e}"		)
																	raise

_SCREAMING_SNAKE_CASE    :      List[str]          =			range(2, 2_0 + 1)
_SCREAMING_SNAKE_CASE    :      Optional[Any]          =			[1_0**k for k in range(ks[-1] + 1)]
_SCREAMING_SNAKE_CASE    :      dict[int, dict[int, list[list[int]]]]          =			{}

def 				SCREAMING_SNAKE_CASE     (      __UpperCamelCase :						Any							,						__UpperCamelCase :						Dict							,						__UpperCamelCase :						Any							,						__UpperCamelCase :						Optional[Any]       ) ->       int:

				"""simple docstring"""







				A__  :	Tuple         =							sum(a_i[j] for j in range(__UpperCamelCase							,						len(__UpperCamelCase       )       )       )
				A__  :	Tuple         =							sum(a_i[j] * base[j] for j in range(min(len(__UpperCamelCase       )							,						__UpperCamelCase       )       )       )

				A__       ,							A__  :	Optional[int]         =							0, 0
				A__  :	List[Any]         =							n - i

				A__  :	Any         =							memo.get(__UpperCamelCase       )

				if sub_memo is not None:
								A__  :	Optional[int]         =							sub_memo.get(__UpperCamelCase       )

								if jumps is not None and len(__UpperCamelCase       ) > 0:
												# find and make the largest jump without going over
												A__  :	List[Any]         =							-1
												for _k in range(len(__UpperCamelCase       ) - 1							,						-1							,						-1       ):
																if jumps[_k][2] <= k and jumps[_k][1] <= max_dn:
																				A__  :	List[str]         =							_k
																				break

												if max_jump >= 0:
																A__       ,							A__       ,							A__  :	List[Any]         =							jumps[max_jump]
																# since the difference between jumps is cached, add c
																A__  :	int         =							diff + c
																for j in range(min(__UpperCamelCase							,						len(__UpperCamelCase       )       )       ):
																				A__       ,							A__  :	List[str]         =							divmod(__UpperCamelCase							,						10       )
																if new_c > 0:
																				add(__UpperCamelCase							,						__UpperCamelCase							,						__UpperCamelCase       )

								else:
												A__  :	List[Any]         =							[]
				else:
								A__  :	Optional[Any]         =							{c: []}
								A__  :	int         =							sub_memo

				if dn >= max_dn or c + diff >= base[k]:
								return diff, dn

				if k > ks[0]:
								while True:
												# keep doing smaller jumps
												A__       ,							A__  :	str         =							next_term(__UpperCamelCase							,						k - 1							,						i + dn							,						__UpperCamelCase       )
												diff += _diff
												dn += terms_jumped

												if dn >= max_dn or c + diff >= base[k]:
																break
				else:
								# would be too small a jump, just compute sequential terms instead
								A__       ,							A__  :	str         =							compute(__UpperCamelCase							,						__UpperCamelCase							,						i + dn							,						__UpperCamelCase       )
								diff += _diff
								dn += terms_jumped

				A__  :	str         =							sub_memo[c]

				# keep jumps sorted by # of terms skipped
				A__  :	List[Any]         =							0
				while j < len(__UpperCamelCase       ):
								if jumps[j][1] > dn:
												break
								j += 1

				# cache the jump for this value digitsum(b) and c
				sub_memo[c].insert(__UpperCamelCase							,						(diff, dn, k)       )
				return (diff, dn)

def 				SCREAMING_SNAKE_CASE     (      __UpperCamelCase :						int							,						__UpperCamelCase :						Optional[int]							,						__UpperCamelCase :						List[str]							,						__UpperCamelCase :						int       ) ->       Any:

				"""simple docstring"""







				if i >= n:
								return 0, i
				if k > len(__UpperCamelCase       ):
								a_i.extend([0 for _ in range(k - len(__UpperCamelCase       )       )]       )

				# note: a_i -> b * 10^k + c
				# ds_b -> digitsum(b)
				# ds_c -> digitsum(c)
				A__  :	Optional[Any]         =							i
				A__       ,							A__       ,							A__  :	Dict         =							0, 0, 0
				for j in range(len(__UpperCamelCase       )       ):
								if j >= k:
												ds_b += a_i[j]
								else:
												ds_c += a_i[j]

				while i < n:
								i += 1
								A__  :	int         =							ds_c + ds_b
								diff += addend
								A__  :	List[Any]         =							0
								for j in range(__UpperCamelCase       ):
												A__  :	Optional[Any]         =							a_i[j] + addend
												A__       ,							A__  :	List[str]         =							divmod(__UpperCamelCase							,						10       )

												ds_c += a_i[j]

								if addend > 0:
												break

				if addend > 0:
								add(__UpperCamelCase							,						__UpperCamelCase							,						__UpperCamelCase       )
				return diff, i - start_i

def 				SCREAMING_SNAKE_CASE     (      __UpperCamelCase :						Dict							,						__UpperCamelCase :						List[Any]							,						__UpperCamelCase :						int       ) ->       Tuple:

				"""simple docstring"""







				for j in range(__UpperCamelCase							,						len(__UpperCamelCase       )       ):
								A__  :	Any         =							digits[j] + addend
								if s >= 10:
												A__       ,							A__  :	Union[str, Any]         =							divmod(__UpperCamelCase							,						10       )
												A__  :	Optional[int]         =							addend // 10 + quotient
								else:
												A__  :	Any         =							s
												A__  :	Dict         =							addend // 10

								if addend == 0:
												break

				while addend > 0:
								A__       ,							A__  :	Dict         =							divmod(__UpperCamelCase							,						10       )
								digits.append(__UpperCamelCase       )

def 				SCREAMING_SNAKE_CASE     (      __UpperCamelCase :						int = 10**15       ) ->       int:

				"""simple docstring"""







				A__  :	List[Any]         =							[1]
				A__  :	Dict         =							1
				A__  :	Tuple         =							0
				while True:
								A__       ,							A__  :	List[str]         =							next_term(__UpperCamelCase							,						20							,						i + dn							,						__UpperCamelCase       )
								dn += terms_jumped
								if dn == n - i:
												break

				A__  :	List[str]         =							0
				for j in range(len(__UpperCamelCase       )       ):
								a_n += digits[j] * 10**j
				return a_n


if __name__ == "__main__":
					print(f"""{solution() = }""")