import numpy as np
import qiskit




def       _snake_case	(   lowerCAmelCase							:   int = 8   , lowerCAmelCase							:   int | None = None	):
		"""simple docstring"""







		SCREAMING_SNAKE_CASE_  :		Optional[Any]				      =    np.random.default_rng(seed=lowerCAmelCase	)

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

		# Quantum Circuit to simulate BB84
		SCREAMING_SNAKE_CASE_  :		List[str]				      =    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.
		SCREAMING_SNAKE_CASE_  :		Optional[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.
		SCREAMING_SNAKE_CASE_  :		Dict				      =    qiskit.execute(lowerCAmelCase   , lowerCAmelCase   , shots=1   , seed_simulator=lowerCAmelCase	)
		# Returns the result of measurement.
		SCREAMING_SNAKE_CASE_  :		Tuple				      =    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.
		SCREAMING_SNAKE_CASE_  :		Optional[int]				      =    ''.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.
		SCREAMING_SNAKE_CASE_  :		Union[str, 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()

from __future__ import annotations





def    __lowercase     (						lowerCamelCase					:     Optional[Any]  ,  lowerCamelCase					:     Dict  ,  lowerCamelCase					:     Union[str, Any]  ,  lowerCamelCase					:     List[str]	):  # noqa: E741
 while r - l > 1:
  UpperCamelCase_					:						Union[str, Any] =					(l + r) // 2
  if v[m] >= key:
   UpperCamelCase_					:						str =					m
  else:
   UpperCamelCase_					:						List[Any] =					m  # noqa: E741
 return r





def    __lowercase     (						lowerCamelCase					:     list[int]	):
 if len(lowerCamelCase	) == 0:
  return 0

 UpperCamelCase_					:						Tuple =					[0] * len(lowerCamelCase	)
 UpperCamelCase_					:						int =					1

 UpperCamelCase_					:						Dict =					v[0]

 for i in range(1  ,  len(lowerCamelCase	)	):
  if v[i] < tail[0]:
   UpperCamelCase_					:						Any =					v[i]
  elif v[i] > tail[length - 1]:
   UpperCamelCase_					:						Dict =					v[i]
   length += 1
  else:
   UpperCamelCase_					:						List[str] =					v[i]

 return length


if __name__ == "__main__":
   import doctest

   doctest.testmod()



