




import json
from typing import Iterator, List, Union

from tokenizers import AddedToken, Regex, Tokenizer, decoders, normalizers, pre_tokenizers, trainers
from tokenizers.implementations.base_tokenizer import BaseTokenizer
from tokenizers.models import Unigram
from tokenizers.processors import TemplateProcessing


class 				UpperCamelCase_    ( UpperCAmelCase__     ):

    '''simple docstring'''






    def __init__(			self      :	List[str]					, UpperCAmelCase__      :	str = "▁"					, UpperCAmelCase__      :	bool = True					, UpperCAmelCase__      :	Union[str, AddedToken] = "<unk>"					, UpperCAmelCase__      :	Union[str, AddedToken] = "</s>"					, UpperCAmelCase__      :	Union[str, AddedToken] = "<pad>"					, )						->Optional[Any]:





           '''simple docstring'''

           A__       =    {
               '''pad''': {'''id''': 0, '''token''': pad_token},
               '''eos''': {'''id''': 1, '''token''': eos_token},
               '''unk''': {'''id''': 2, '''token''': unk_token},
           }

           A__       =    [None] * len(self.special_tokens)
           for token_dict in self.special_tokens.values():
                  A__       =    token_dict['''token''']

           A__       =    Tokenizer(Unigram())

           A__       =    normalizers.Sequence(
               [
                   normalizers.Nmt(),
                   normalizers.NFKC(),
                   normalizers.Replace(Regex(''' {2,}''')					, ''' '''),
                   normalizers.Lowercase(),
               ])
           A__       =    pre_tokenizers.Sequence(
               [
                   pre_tokenizers.Metaspace(replacement=UpperCAmelCase__					, add_prefix_space=UpperCAmelCase__),
                   pre_tokenizers.Digits(individual_digits=UpperCAmelCase__),
                   pre_tokenizers.Punctuation(),
               ])
           A__       =    decoders.Metaspace(replacement=UpperCAmelCase__					, add_prefix_space=UpperCAmelCase__)

           A__       =    TemplateProcessing(
               single=f"""$A {self.special_tokens["eos"]["token"]}"""					, special_tokens=[(self.special_tokens['''eos''']['''token'''], self.special_tokens['''eos''']['''id'''])]					, )

           A__       =    {
               '''model''': '''SentencePieceUnigram''',
               '''replacement''': replacement,
               '''add_prefix_space''': add_prefix_space,
           }

           super().__init__(UpperCAmelCase__					, UpperCAmelCase__)


    def        SCREAMING_SNAKE_CASE							(			self      :	Any					, UpperCAmelCase__      :	Union[str, List[str]]					, UpperCAmelCase__      :	int = 8_000					, UpperCAmelCase__      :	bool = True					, )						->Tuple:





           '''simple docstring'''

           A__       =    trainers.UnigramTrainer(
               vocab_size=UpperCAmelCase__					, special_tokens=self.special_tokens_list					, show_progress=UpperCAmelCase__					, )

           if isinstance(UpperCAmelCase__					, UpperCAmelCase__):
                  A__       =    [files]
           self._tokenizer.train(UpperCAmelCase__					, trainer=UpperCAmelCase__)

           self.add_unk_id()


    def        SCREAMING_SNAKE_CASE							(			self      :	Tuple					, UpperCAmelCase__      :	Union[Iterator[str], Iterator[Iterator[str]]]					, UpperCAmelCase__      :	int = 8_000					, UpperCAmelCase__      :	bool = True					, )						->List[Any]:





           '''simple docstring'''

           A__       =    trainers.UnigramTrainer(
               vocab_size=UpperCAmelCase__					, special_tokens=self.special_tokens_list					, show_progress=UpperCAmelCase__					, )

           self._tokenizer.train_from_iterator(UpperCAmelCase__					, trainer=UpperCAmelCase__)

           self.add_unk_id()





    def        SCREAMING_SNAKE_CASE							(			self      :	Any)						->str:





           '''simple docstring'''

           A__       =    json.loads(self._tokenizer.to_str())

           A__       =    self.special_tokens['''unk''']['''id''']

           A__       =    Tokenizer.from_str(json.dumps(UpperCAmelCase__))



"""simple docstring"""




import numpy as np
import qiskit





def 							SCREAMING_SNAKE_CASE     (			_lowerCamelCase						:       int = 8			,_lowerCamelCase						:       int | None = None	)       ->      str:
  _lowerCAmelCase						:       int  			=     np.random.default_rng(seed=_lowerCamelCase	)

  # Roughly 25% of the qubits will contribute to the key.
  # So we take more than we need.
  _lowerCAmelCase						:       Tuple  			=     6 * key_len
  # Measurement basis for Alice's qubits.
  _lowerCAmelCase						:       Dict  			=     rng.integers(2			,size=_lowerCamelCase	)
  # The set of states Alice will prepare.
  _lowerCAmelCase						:       Tuple  			=     rng.integers(2			,size=_lowerCamelCase	)
  # Measurement basis for Bob's qubits.
  _lowerCAmelCase						:       Union[str, Any]  			=     rng.integers(2			,size=_lowerCamelCase	)

  # Quantum Circuit to simulate BB84
  _lowerCAmelCase						:       Dict  			=     qiskit.QuantumCircuit(_lowerCamelCase			,name="""BB84"""	)

  # Alice prepares her qubits according to rules above.
  for index, _ in enumerate(_lowerCamelCase	):
    if alice_state[index] == 1:
      bbaa_circ.x(_lowerCamelCase	)
    if alice_basis[index] == 1:
      bbaa_circ.h(_lowerCamelCase	)
  bbaa_circ.barrier()

  # Bob measures the received qubits according to rules above.
  for index, _ in enumerate(_lowerCamelCase	):
    if bob_basis[index] == 1:
      bbaa_circ.h(_lowerCamelCase	)

  bbaa_circ.barrier()
  bbaa_circ.measure_all()

  # Simulate the quantum circuit.
  _lowerCAmelCase						:       int  			=     qiskit.Aer.get_backend("""aer_simulator"""	)
  # We only need to run one shot because the key is unique.
  # Multiple shots will produce the same key.
  _lowerCAmelCase						:       List[str]  			=     qiskit.execute(_lowerCamelCase			,_lowerCamelCase			,shots=1			,seed_simulator=_lowerCamelCase	)
  # Returns the result of measurement.
  _lowerCAmelCase						:       List[Any]  			=     job.result().get_counts(_lowerCamelCase	).most_frequent()

  # Extracting the generated key from the simulation results.
  # Only keep measurement results where Alice and Bob chose the same basis.
  _lowerCAmelCase						:       str  			=     """""".join(
      [
          result_bit
          for alice_basis_bit, bob_basis_bit, result_bit in zip(
              _lowerCamelCase			,_lowerCamelCase			,_lowerCamelCase	)
          if alice_basis_bit == bob_basis_bit
      ]	)

  # Get final key. Pad with 0 if too short, otherwise truncate.
  _lowerCAmelCase						:       List[Any]  			=     gen_key[:key_len] if len(_lowerCamelCase	) >= key_len else gen_key.ljust(_lowerCamelCase			,"""0"""	)
  return key


if __name__ == "__main__":
     print(F"""The generated key is : {bbaa(8, seed=0)}""")
     from doctest import testmod

     testmod()




