






import jax
import jax.numpy as jnp
from bigbird_flax import FlaxBigBirdForNaturalQuestions
from datasets import load_from_disk

from transformers import BigBirdTokenizerFast


__lowerCamelCase						= {0: 'null', 1: 'short', 2: 'long', 3: 'yes', 4: 'no'}
__lowerCamelCase						= set(''.join(['‘', '’', '´', '`', '.', ',', '-', '\"']))






def    UpperCamelCase__  (   UpperCAmelCase    ,	UpperCAmelCase=0    ,	UpperCAmelCase=None     )     ->		Any:







							"""simple docstring"""





							return [" ".join(x.split(''' '''     )[begin:end]     ) for x in answers if len(x.split(''' '''     )     ) > 1]






def    UpperCamelCase__  (   UpperCAmelCase    ,	UpperCAmelCase=False     )     ->		Dict:







							"""simple docstring"""





							if make_sub_answers:
														# if answers are longer than one word, make sure a predictions is correct if it coresponds to the complete 1: or :-1 sub word
														# *e.g.* if the correct answer contains a prefix such as "the", or "a"
														_a  :    str			=						(
														    given_answers + get_sub_answers(_snake_case    ,	begin=1     ) + get_sub_answers(_snake_case    ,	end=-1     )
														)
							_a  :    str			=						[]
							for answer in given_answers:
														_a  :    Any			=						answer.replace('''_'''    ,	''' '''     ).lower()
														_a  :    List[Any]			=						''''''.join(c if c not in PUNCTUATION_SET_TO_EXCLUDE else ''' ''' for c in alias     )
														answers.append(''' '''.join(alias.split()     ).strip()     )
							return set(_snake_case     )






def    UpperCamelCase__  (   UpperCAmelCase    ,	UpperCAmelCase    ,	UpperCAmelCase=1    ,	UpperCAmelCase=100     )     ->		int:







							"""simple docstring"""





							_a		,					_a  :    Tuple			=						jax.lax.top_k(_snake_case    ,	_snake_case     )
							_a		,					_a  :    Optional[Any]			=						jax.lax.top_k(_snake_case    ,	_snake_case     )

							_a  :    str			=						best_end_idx[:, None] - best_start_idx[None, :]
							_a  :    int			=						jnp.logical_or(widths < 0    ,	widths > max_size     )
							_a  :    Dict			=						(best_end_scores[:, None] + best_start_scores[None, :]) - (1e8 * mask)
							_a  :    Optional[int]			=						jnp.argmax(_snake_case     ).item()

							return best_start_idx[best_score % top_k], best_end_idx[best_score // top_k]






def    UpperCamelCase__  (   UpperCAmelCase     )     ->		Tuple:







							"""simple docstring"""





							_a  :    int			=						sample['''question''']['''text''']
							_a  :    int			=						sample['''document''']['''tokens''']['''token''']
							_a  :    List[str]			=						sample['''document''']['''tokens''']['''is_html''']
							_a  :    str			=						sample['''annotations''']['''long_answer''']
							_a  :    Tuple			=						sample['''annotations''']['''short_answers''']

							_a  :    Union[str, Any]			=						''' '''.join([context[i] for i in range(len(_snake_case     )     ) if not is_html[i]]     )

							# 0 - No ; 1 - Yes
							for answer in sample["annotations"]["yes_no_answer"]:
														if answer == 0 or answer == 1:
																					return {
																					    "question": question,
																					    "context": context_string,
																					    "short": [],
																					    "long": [],
																					    "category": "no" if answer == 0 else "yes",
																					}

							_a  :    Dict			=						[]
							for s in short_answers:
														short_targets.extend(s['''text''']     )
							_a  :    Union[str, Any]			=						list(set(_snake_case     )     )

							_a  :    Optional[int]			=						[]
							for s in long_answers:
														if s["start_token"] == -1:
																					continue
														_a  :    List[Any]			=						context[s['''start_token'''] : s['''end_token''']]
														_a  :    Dict			=						is_html[s['''start_token'''] : s['''end_token''']]
														_a  :    Dict			=						''' '''.join([answer[i] for i in range(len(_snake_case     )     ) if not html[i]]     )
														if new_answer not in long_targets:
																					long_targets.append(_snake_case     )

							_a  :    str			=						'''long_short''' if len(short_targets + long_targets     ) > 0 else '''null'''

							return {
							    "question": question,
							    "context": context_string,
							    "short": short_targets,
							    "long": long_targets,
							    "category": category,
							}






def    UpperCamelCase__  (   )     ->		int:







							"""simple docstring"""





							_a  :    Optional[int]			=						load_from_disk('''natural-questions-validation'''     )
							_a  :    Tuple			=						dataset.map(_snake_case     ).remove_columns(['''annotations''', '''document''', '''id''']     )
							print(_snake_case     )

							_a  :    str			=						dataset.filter(lambda UpperCAmelCase     : (len(x['''question''']     ) + len(x['''context''']     )) < 4 * 4096     )
							_a  :    Optional[Any]			=						short_validation_dataset.filter(lambda UpperCAmelCase     : x["category"] != "null"     )
							short_validation_dataset

							_a  :    Any			=						'''vasudevgupta/flax-bigbird-natural-questions'''
							_a  :    Optional[int]			=						FlaxBigBirdForNaturalQuestions.from_pretrained(_snake_case     )
							_a  :    int			=						BigBirdTokenizerFast.from_pretrained(_snake_case     )

							@jax.jit
							def forward(*UpperCAmelCase    ,	**UpperCAmelCase     ):
														_a		,					_a		,					_a  :    Optional[int]			=						model(*_snake_case    ,	**_snake_case     )
														return start_logits, end_logits, jnp.argmax(_snake_case    ,	axis=-1     )

							def evaluate(UpperCAmelCase     ):
														# encode question and context so that they are separated by a tokenizer.sep_token and cut at max_length
														_a  :    Union[str, Any]			=						tokenizer(
														    example['''question''']    ,	example['''context''']    ,	return_tensors='''np'''    ,	max_length=4096    ,	padding='''max_length'''    ,	truncation=_snake_case    ,	)

														_a		,					_a		,					_a  :    Union[str, Any]			=						forward(**_snake_case     )

														_a  :    int			=						CATEGORY_MAPPING[category.item()]

														_a  :    List[str]			=						example['''long'''] + example['''short''']
														if example["category"] in ["yes", "no", "null"]:
																					_a  :    Optional[Any]			=						[example['''category''']]
														_a  :    Any			=						example['''category'''] != '''null'''
														# Now target can be: "yes", "no", "null", "list of long & short answers"

														if predicted_category in ["yes", "no", "null"]:
																					_a  :    int			=						[predicted_category]
																					_a  :    Optional[int]			=						example['''output'''] == example['''targets''']
																					_a  :    str			=						predicted_category != '''null'''
																					return example

														_a  :    List[Any]			=						38 if predicted_category == '''short''' else 1024
														_a		,					_a  :    Tuple			=						get_best_valid_start_end_idx(
														    start_scores[0]    ,	end_scores[0]    ,	top_k=8    ,	max_size=_snake_case     )

														_a  :    Tuple			=						inputs['''input_ids'''][0].tolist()
														_a  :    Any			=						[tokenizer.decode(input_ids[start_score : end_score + 1]     )]

														_a  :    Dict			=						expand_to_aliases(example['''targets''']    ,	make_sub_answers=_snake_case     )
														_a  :    List[str]			=						expand_to_aliases(example['''output''']     )

														# some preprocessing to both prediction and answer
														_a  :    List[str]			=						{''''''.join(a.split()     ) for a in answers}
														_a  :    List[Any]			=						{''''''.join(p.split()     ) for p in predictions}
														_a  :    int			=						{s for s in predictions if s not in ['''``''', '''\'\'''', '''`''', '''\'''']}

														# if there is a common element, it's a exact match
														_a  :    str			=						len(list(answers & predictions     )     ) > 0
														_a  :    Union[str, Any]			=						predicted_category != '''null''' and len(_snake_case     ) > 0

														return example

							_a  :    List[str]			=						short_validation_dataset.map(_snake_case     )

							_a  :    Any			=						len(_snake_case     )
							_a  :    int			=						len(short_validation_dataset.filter(lambda UpperCAmelCase     : x["match"] == 1     )     )
							print('''EM score:'''    ,	(matched / total) * 100    ,	'''%'''     )


if __name__ == "__main__":
						main()





from itertools import permutations



def    UpperCAmelCase							(  _snake_case = 5				):
							if gon_side < 3 or gon_side > 5:
														raise ValueError('''gon_side must be in the range [3, 5]'''				)

							# Since it's 16, we know 10 is on the outer ring
							# Put the big numbers at the end so that they are never the first number
							lowerCAmelCase =		list(range(gon_side + 1    ,			0    ,			-1				)				)
							lowerCAmelCase =		list(range(gon_side + 2    ,			gon_side * 2 + 1				)				)

							for perm in permutations(small_numbers + big_numbers				):
														lowerCAmelCase =		generate_gon_ring(_snake_case    ,			list(_snake_case				)				)
														if is_magic_gon(_snake_case				):
																					return int(''''''.join(str(_snake_case				) for n in numbers				)				)

							lowerCAmelCase =		F"""Magic {gon_side}-gon ring is impossible"""
							raise ValueError(_snake_case				)



def    UpperCAmelCase							(  _snake_case    ,			_snake_case				):
							lowerCAmelCase =		[0] * (gon_side * 3)
							lowerCAmelCase =		perm[0:3]
							perm.append(perm[1]				)

							lowerCAmelCase =		1 if gon_side < 5 else 2

							for i in range(1    ,			len(_snake_case				) // 3 + magic_number				):
														lowerCAmelCase =		perm[2 * i + 1]
														lowerCAmelCase =		result[3 * i - 1]
														lowerCAmelCase =		perm[2 * i + 2]

							return result



def    UpperCAmelCase							(  _snake_case				):
							if len(_snake_case				) % 3 != 0:
														raise ValueError('''a gon ring should have a length that is a multiple of 3'''				)

							if min(numbers[::3]				) != numbers[0]:
														return False

							lowerCAmelCase =		sum(numbers[:3]				)

							return all(sum(numbers[i : i + 3]				) == total for i in range(3    ,			len(_snake_case				)    ,			3				)				)


if __name__ == "__main__":
		print(solution())



