
import os
import unicodedata
from shutil import copyfile
from typing import Any, Dict, List, Optional, Tuple

import sentencepiece as spm

from ...tokenization_utils import AddedToken, PreTrainedTokenizer
from ...utils import SPIECE_UNDERLINE, logging


__magic_name__  							=	logging.get_logger(__name__)

__magic_name__  							=	{'''vocab_file''': '''spiece.model'''}

__magic_name__  							=	{
    '''vocab_file''': {
        '''xlnet-base-cased''': '''https://huggingface.co/xlnet-base-cased/resolve/main/spiece.model''',
        '''xlnet-large-cased''': '''https://huggingface.co/xlnet-large-cased/resolve/main/spiece.model''',
    }
}

__magic_name__  							=	{
    '''xlnet-base-cased''': None,
    '''xlnet-large-cased''': None,
}

# Segments (not really needed)
__magic_name__  							=	0
__magic_name__  							=	1
__magic_name__  							=	2
__magic_name__  							=	3
__magic_name__  							=	4




class        _SCREAMING_SNAKE_CASE	(   __UpperCamelCase			):
      _A    :		List[Any]     						=  VOCAB_FILES_NAMES
      _A    :		Optional[int]     						=  PRETRAINED_VOCAB_FILES_MAP
      _A    :		List[str]     						=  PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
      _A    :		str     						=  'left'
      def __init__(      self		,						lowerCamelCase		,						lowerCamelCase=False		,						lowerCamelCase=True		,						lowerCamelCase=False		,						lowerCamelCase="<s>"		,						lowerCamelCase="</s>"		,						lowerCamelCase="<unk>"		,						lowerCamelCase="<sep>"		,						lowerCamelCase="<pad>"		,						lowerCamelCase="<cls>"		,						lowerCamelCase="<mask>"		,						lowerCamelCase=["<eop>", "<eod>"]		,						lowerCamelCase = None		,						**lowerCamelCase		,						):
          # Mask token behave like a normal word, i.e. include the space before it
          snake_case__    =					AddedToken(lowerCamelCase		,						lstrip=lowerCamelCase		,						rstrip=lowerCamelCase			) if isinstance(lowerCamelCase		,						lowerCamelCase			) else mask_token

          snake_case__    =					{} if sp_model_kwargs is None else sp_model_kwargs

          super().__init__(
              do_lower_case=lowerCamelCase		,						remove_space=lowerCamelCase		,						keep_accents=lowerCamelCase		,						bos_token=lowerCamelCase		,						eos_token=lowerCamelCase		,						unk_token=lowerCamelCase		,						sep_token=lowerCamelCase		,						pad_token=lowerCamelCase		,						cls_token=lowerCamelCase		,						mask_token=lowerCamelCase		,						additional_special_tokens=lowerCamelCase		,						sp_model_kwargs=self.sp_model_kwargs		,						**lowerCamelCase		,						)

          snake_case__    =					3

          snake_case__    =					do_lower_case
          snake_case__    =					remove_space
          snake_case__    =					keep_accents
          snake_case__    =					vocab_file

          snake_case__    =					spm.SentencePieceProcessor(**self.sp_model_kwargs			)
          self.sp_model.Load(lowerCamelCase			)
      @property
      def A_      (      self			):
          return len(self.sp_model			)
      def A_      (      self			):
          snake_case__    =					{self.convert_ids_to_tokens(lowerCamelCase			): i for i in range(self.vocab_size			)}
          vocab.update(self.added_tokens_encoder			)
          return vocab
      def __getstate__(      self			):
          snake_case__    =					self.__dict__.copy()
          snake_case__    =					None
          return state
      def __setstate__(      self		,						lowerCamelCase			):
          snake_case__    =					d

          # for backward compatibility
          if not hasattr(self		,						"sp_model_kwargs"			):
              snake_case__    =					{}

          snake_case__    =					spm.SentencePieceProcessor(**self.sp_model_kwargs			)
          self.sp_model.Load(self.vocab_file			)
      def A_      (      self		,						lowerCamelCase			):
          if self.remove_space:
              snake_case__    =					" ".join(inputs.strip().split()			)
          else:
              snake_case__    =					inputs
          snake_case__    =					outputs.replace("``"		,						"\""			).replace("''"		,						"\""			)

          if not self.keep_accents:
              snake_case__    =					unicodedata.normalize("NFKD"		,						lowerCamelCase			)
              snake_case__    =					"".join([c for c in outputs if not unicodedata.combining(lowerCamelCase			)]			)
          if self.do_lower_case:
              snake_case__    =					outputs.lower()

          return outputs
      def A_      (      self		,						lowerCamelCase			):
          snake_case__    =					self.preprocess_text(lowerCamelCase			)
          snake_case__    =					self.sp_model.encode(lowerCamelCase		,						out_type=lowerCamelCase			)
          snake_case__    =					[]
          for piece in pieces:
              if len(lowerCamelCase			) > 1 and piece[-1] == str(","			) and piece[-2].isdigit():
                  snake_case__    =					self.sp_model.EncodeAsPieces(piece[:-1].replace(lowerCamelCase		,						""			)			)
                  if piece[0] != SPIECE_UNDERLINE and cur_pieces[0][0] == SPIECE_UNDERLINE:
                      if len(cur_pieces[0]			) == 1:
                          snake_case__    =					cur_pieces[1:]
                      else:
                          snake_case__    =					cur_pieces[0][1:]
                  cur_pieces.append(piece[-1]			)
                  new_pieces.extend(lowerCamelCase			)
              else:
                  new_pieces.append(lowerCamelCase			)

          return new_pieces
      def A_      (      self		,						lowerCamelCase			):
          return self.sp_model.PieceToId(lowerCamelCase			)
      def A_      (      self		,						lowerCamelCase			):
          return self.sp_model.IdToPiece(lowerCamelCase			)
      def A_      (      self		,						lowerCamelCase			):
          snake_case__    =					"".join(lowerCamelCase			).replace(lowerCamelCase		,						" "			).strip()
          return out_string
      def A_      (      self		,						lowerCamelCase		,						lowerCamelCase = False		,						lowerCamelCase = None		,						lowerCamelCase = True		,						**lowerCamelCase		,						):
          snake_case__    =					kwargs.pop("use_source_tokenizer"		,						lowerCamelCase			)

          snake_case__    =					self.convert_ids_to_tokens(lowerCamelCase		,						skip_special_tokens=lowerCamelCase			)

          # To avoid mixing byte-level and unicode for byte-level BPT
          # we need to build string separately for added tokens and byte-level tokens
          # cf. https://github.com/huggingface/transformers/issues/1133
          snake_case__    =					[]
          snake_case__    =					[]
          for token in filtered_tokens:
              if skip_special_tokens and token in self.all_special_ids:
                  continue
              if token in self.added_tokens_encoder:
                  if current_sub_text:
                      sub_texts.append(self.convert_tokens_to_string(lowerCamelCase			)			)
                      snake_case__    =					[]
                  sub_texts.append(lowerCamelCase			)
              else:
                  current_sub_text.append(lowerCamelCase			)
          if current_sub_text:
              sub_texts.append(self.convert_tokens_to_string(lowerCamelCase			)			)

          # Mimic the behavior of the Rust tokenizer:
          # By default, there are no spaces between special tokens
          snake_case__    =					"".join(lowerCamelCase			)

          snake_case__    =					(
              clean_up_tokenization_spaces
              if clean_up_tokenization_spaces is not None
              else self.clean_up_tokenization_spaces
          )
          if clean_up_tokenization_spaces:
              snake_case__    =					self.clean_up_tokenization(lowerCamelCase			)
              return clean_text
          else:
              return text
      def A_      (      self		,						lowerCamelCase		,						lowerCamelCase = None			):
          snake_case__    =					[self.sep_token_id]
          snake_case__    =					[self.cls_token_id]
          if token_ids_a is None:
              return token_ids_a + sep + cls
          return token_ids_a + sep + token_ids_a + sep + cls
      def A_      (      self		,						lowerCamelCase		,						lowerCamelCase = None		,						lowerCamelCase = False			):

          if already_has_special_tokens:
              return super().get_special_tokens_mask(
                  token_ids_a=lowerCamelCase		,						token_ids_a=lowerCamelCase		,						already_has_special_tokens=lowerCamelCase			)

          if token_ids_a is not None:
              return ([0] * len(lowerCamelCase			)) + [1] + ([0] * len(lowerCamelCase			)) + [1, 1]
          return ([0] * len(lowerCamelCase			)) + [1, 1]
      def A_      (      self		,						lowerCamelCase		,						lowerCamelCase = None			):
          snake_case__    =					[self.sep_token_id]
          snake_case__    =					[2]

          if token_ids_a is None:
              return len(token_ids_a + sep			) * [0] + cls_segment_id
          return len(token_ids_a + sep			) * [0] + len(token_ids_a + sep			) * [1] + cls_segment_id



      def A_      (      self		,						lowerCamelCase		,						lowerCamelCase = None			):
          if not os.path.isdir(lowerCamelCase			):
              logger.error(F"""Vocabulary path ({save_directory}) should be a directory"""			)
              return
          snake_case__    =					os.path.join(
              lowerCamelCase		,						(filename_prefix + "-" if filename_prefix else "") + VOCAB_FILES_NAMES["vocab_file"]			)

          if os.path.abspath(self.vocab_file			) != os.path.abspath(lowerCamelCase			) and os.path.isfile(self.vocab_file			):
              copyfile(self.vocab_file		,						lowerCamelCase			)
          elif not os.path.isfile(self.vocab_file			):
              with open(lowerCamelCase		,						"wb"			) as fi:
                  snake_case__    =					self.sp_model.serialized_model_proto()
                  fi.write(lowerCamelCase			)

          return (out_vocab_file,)





import math

__magic_name__  							=	10
__magic_name__  							=	7
__magic_name__  							=	BALLS_PER_COLOUR * NUM_COLOURS





def 						SCREAMING_SNAKE_CASE__     (   __lowerCAmelCase = 20				):
    snake_case__    =					math.comb(__lowerCAmelCase     ,		__lowerCAmelCase				)
    snake_case__    =					math.comb(NUM_BALLS - BALLS_PER_COLOUR     ,		__lowerCAmelCase				)

    snake_case__    =					NUM_COLOURS * (1 - missing_colour / total)

    return F"""{result:.9f}"""


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



