
import numpy as np
import qiskit






def        lowerCamelCase__    (    __lowerCAmelCase  :  str   ,							__lowerCAmelCase  :  int    ):




			"""simple docstring"""


			lowerCAmelCase_      =     qiskit.QuantumCircuit(num_qubits + 1    )

			# First, let's deal with the case in which oracle is balanced
			if case == "balanced":
						# First generate a random number that tells us which CNOTs to
						# wrap in X-gates:
						lowerCAmelCase_      =     np.random.randint(1   ,							2**num_qubits    )
						# Next, format 'b' as a binary string of length 'n', padded with zeros:
						lowerCAmelCase_      =     format(__lowerCAmelCase   ,							F"""0{num_qubits}b"""    )
						# Next, we place the first X-gates. Each digit in our binary string
						# corresponds to a qubit, if the digit is 0, we do nothing, if it's 1
						# we apply an X-gate to that qubit:
						for index, bit in enumerate(__lowerCAmelCase    ):
									if bit == "1":
												oracle_qc.x(__lowerCAmelCase    )
        # Do the controlled-NOT gates for each qubit, using the output qubit
        # as the target:
						for index in range(__lowerCAmelCase    ):
									oracle_qc.cx(__lowerCAmelCase   ,							__lowerCAmelCase    )
						# Next, place the final X-gates
						for index, bit in enumerate(__lowerCAmelCase    ):
									if bit == "1":
												oracle_qc.x(__lowerCAmelCase    )

    # Case in which oracle is constant
			if case == "constant":
						# First decide what the fixed output of the oracle will be
						# (either always 0 or always 1)
						lowerCAmelCase_      =     np.random.randint(2    )
						if output == 1:
									oracle_qc.x(__lowerCAmelCase    )

			lowerCAmelCase_      =     oracle_qc.to_gate()
			lowerCAmelCase_      =     "Oracle"  # To show when we display the circuit
			return oracle_gate






def        lowerCamelCase__    (    __lowerCAmelCase  :  qiskit.QuantumCircuit   ,							__lowerCAmelCase  :  int    ):




			"""simple docstring"""


			lowerCAmelCase_      =     qiskit.QuantumCircuit(num_qubits + 1   ,							__lowerCAmelCase    )
			# Set up the output qubit:
			dj_circuit.x(__lowerCAmelCase    )
			dj_circuit.h(__lowerCAmelCase    )
			# And set up the input register:
			for qubit in range(__lowerCAmelCase    ):
						dj_circuit.h(__lowerCAmelCase    )
			# Let's append the oracle gate to our circuit:
			dj_circuit.append(__lowerCAmelCase   ,							range(num_qubits + 1    )    )
			# Finally, perform the H-gates again and measure:
			for qubit in range(__lowerCAmelCase    ):
						dj_circuit.h(__lowerCAmelCase    )

			for i in range(__lowerCAmelCase    ):
						dj_circuit.measure(__lowerCAmelCase   ,							__lowerCAmelCase    )

			return dj_circuit






def        lowerCamelCase__    (    __lowerCAmelCase  :  str   ,							__lowerCAmelCase  :  int    ):




			"""simple docstring"""


			lowerCAmelCase_      =     qiskit.Aer.get_backend("aer_simulator"    )

			lowerCAmelCase_      =     dj_oracle(__lowerCAmelCase   ,							__lowerCAmelCase    )
			lowerCAmelCase_      =     dj_algorithm(__lowerCAmelCase   ,							__lowerCAmelCase    )

			# Execute the circuit on the simulator
			lowerCAmelCase_      =     qiskit.execute(__lowerCAmelCase   ,							__lowerCAmelCase   ,							shots=1000    )

			# Return the histogram data of the results of the experiment.
			return job.result().get_counts(__lowerCAmelCase    )


if __name__ == "__main__":
			print(f"""Deutsch Jozsa - Constant Oracle: {deutsch_jozsa('constant', 3)}""")
			print(f"""Deutsch Jozsa - Balanced Oracle: {deutsch_jozsa('balanced', 3)}""")





import json
import os
from dataclasses import dataclass

import numpy as np
import pyarrow as pa

import datasets
from utils import get_duration


_A       =					10_00_00_00_00_00
_A       =					1_00_00

_A,				_A       =					os.path.split(__file__)
_A       =					os.path.join(RESULTS_BASEPATH, "results", RESULTS_FILENAME.replace(".py", ".json"))






def        lowerCamelCase__    (    __lowerCAmelCase  :  int   ,							__lowerCAmelCase  :  int    ):




			"""simple docstring"""


			lowerCAmelCase_      =     pa.Table.from_pydict({"col": [0] * chunk_size}    )
			lowerCAmelCase_      =     pa.concat_tables([table] * (num_examples // chunk_size)    )
			return datasets.Dataset(__lowerCAmelCase   ,							fingerprint="table_100B"    )





@dataclass
class      _lowerCAmelCase :
				_lowercase      		=42
				_lowercase      		=42
				_lowercase      		=42
				_lowercase      		=42




				def 					__a						( self					)    ->				List[Any]:
							lowerCAmelCase_      =     np.random.default_rng(self.seed					)
							lowerCAmelCase_      =     rng.integers(low=self.low    ,    high=self.high    ,    size=self.size					).tolist()




				def __iter__( self					)    ->				List[str]:
							return iter(self._sampled_values					)




				def __len__( self					)    ->				Optional[int]:
							return self.size






@get_duration
def        lowerCamelCase__    (    __lowerCAmelCase  :  datasets.Dataset    ):




			"""simple docstring"""


			lowerCAmelCase_      =     dataset[0]






@get_duration
def        lowerCamelCase__    (    __lowerCAmelCase  :  datasets.Dataset    ):




			"""simple docstring"""


			lowerCAmelCase_      =     dataset[-1]






@get_duration
def        lowerCamelCase__    (    __lowerCAmelCase  :  datasets.Dataset    ):




			"""simple docstring"""


			lowerCAmelCase_      =     dataset[range(len(__lowerCAmelCase    ) // 2   ,							len(__lowerCAmelCase    ) // 2 + 1024    )]






@get_duration
def        lowerCamelCase__    (    __lowerCAmelCase  :  datasets.Dataset    ):




			"""simple docstring"""


			lowerCAmelCase_      =     dataset[RandIter(0   ,							len(__lowerCAmelCase    )   ,							1024   ,							seed=42    )]






def        lowerCamelCase__    (    ):




			"""simple docstring"""


			lowerCAmelCase_      =     {"num examples": SPEED_TEST_N_EXAMPLES}
			lowerCAmelCase_      =     (get_first_row, get_last_row, get_batch_of_aaaa_rows, get_batch_of_aaaa_random_rows)
			print("generating dataset"    )
			lowerCAmelCase_      =     generate_100B_dataset(num_examples=__lowerCAmelCase   ,							chunk_size=__lowerCAmelCase    )
			print("Functions"    )
			for func in functions:
						print(func.__name__    )
						lowerCAmelCase_      =     func(__lowerCAmelCase    )

			with open(__lowerCAmelCase   ,							"wb"    ) as f:
						f.write(json.dumps(__lowerCAmelCase    ).encode("utf-8"    )    )


if __name__ == "__main__":  # useful to run the profiler
			benchmark_table_100B()



