
import numpy as np
import qiskit


def     UpperCamelCase      (					__lowerCamelCase  :				str       ,      __lowerCamelCase  :				int					):
       snake_case :     str           =   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:
              snake_case :     List[Any]           =   np.random.randint(1       ,      2**num_qubits					)
              # Next, format 'b' as a binary string of length 'n', padded with zeros:
              snake_case :     Optional[Any]           =   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)
              snake_case :     Optional[int]           =   np.random.randint(2					)
              if output == 1:
                     oracle_qc.x(__lowerCamelCase					)

       snake_case :     List[str]           =   oracle_qc.to_gate()
       snake_case :     Dict           =   "Oracle"  # To show when we display the circuit
       return oracle_gate


def     UpperCamelCase      (					__lowerCamelCase  :				qiskit.QuantumCircuit       ,      __lowerCamelCase  :				int					):
       snake_case :     Tuple           =   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     UpperCamelCase      (					__lowerCamelCase  :				str       ,      __lowerCamelCase  :				int					):
       snake_case :     str           =   qiskit.Aer.get_backend("aer_simulator"					)

       snake_case :     Tuple           =   dj_oracle(__lowerCamelCase       ,      __lowerCamelCase					)
       snake_case :     int           =   dj_algorithm(__lowerCamelCase       ,      __lowerCamelCase					)

       # Execute the circuit on the simulator
       snake_case :     Union[str, Any]           =   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)}')







def     UpperCamelCase      (					__lowerCamelCase  :				int = 998001					):
       snake_case :     Optional[Any]           =   0
       for i in range(999       ,      99       ,      -1					):  # 3 digit numbers range from 999 down to 100
              for j in range(999       ,      99       ,      -1					):
                     snake_case :     Tuple           =   str(i * j					)
                     if product_string == product_string[::-1] and i * j < n:
                            snake_case :     str           =   max(__lowerCamelCase       ,      i * j					)
       return answer


if __name__ == "__main__":
   print(F'{solution() = }')





