my_list = [1, 3, 5, 2, 4, 9, 5, 8, 0, 7, 6]

def the_oracle(my_input):
    winner = 7
    return my_input == winner

for index, trial_number in enumerate(my_list):
    if the_oracle(trial_number):
        print(f"Found the winner at index {index}!")
        print(f"{index+1} calls made")
        break

from qiskit import *
from qiskit.visualization import plot_histogram, array_to_latex
from qiskit.providers.ibmq import least_busy
import matplotlib.pyplot as plt
import numpy as np

grover_circuit = QuantumCircuit(2)

def init_state(qc, qubits):
    for q in qubits:
        qc.h(q)
    return qc

grover_circuit = init_state(grover_circuit, [0, 1])
grover_circuit.draw("mpl")

#define the oracle circuit
def oracle(qc, qubits):
    qc.cz(qubits[0], qubits[1])

qc = QuantumCircuit(2)
oracle(qc, [0, 1])
qc.draw("mpl")

usim = Aer.get_backend('aer_simulator')
qc.save_unitary()
qobj = assemble(qc)
unitary = usim.run(qobj).result().get_unitary()

array_to_latex(unitary, prefix="\\text{One can see that only the state }\ket{11}\\text{ has been flipped: }\n")

def diffusion(qc, qubits):
    qc.h([0, 1])

    qc.z([0, 1])
    qc.cz(0, 1)

    qc.h([0, 1])

grover_circuit.barrier()
oracle(grover_circuit, [0, 1])
grover_circuit.barrier()
diffusion(grover_circuit, [0, 1])
grover_circuit.measure_all()
grover_circuit.draw("mpl")

# Let's see if the final statevector matches our expectations
sv_sim = Aer.get_backend('statevector_simulator')
result = sv_sim.run(grover_circuit).result()
statevec = result.get_statevector()
statevec

aer_sim = Aer.get_backend('aer_simulator')
result = execute(grover_circuit, aer_sim, shots=1024).result()
result.get_counts()

# Load IBM Q account and get the least busy backend device
# Run the following line with your API token to use IBM's own quantum computers
#IBMQ.save_account('')
provider = IBMQ.load_account()
provider = IBMQ.get_provider("ibm-q")
device = least_busy(provider.backends(filters=lambda x: x.configuration().n_qubits >= 3 and 
                                   not x.configuration().simulator and x.status().operational==True))
print("Running on current least busy device: ", device)

# Run our circuit on the least busy backend. Monitor the execution of the job in the queue
from qiskit.tools.monitor import job_monitor
transpiled_grover_circuit = transpile(grover_circuit, device, optimization_level=3)
job = device.run(transpiled_grover_circuit)
job_monitor(job, interval=2)

# Get the results from the computation
results = job.result()
answer = results.get_counts(grover_circuit)
plot_histogram(answer)

grover_circuit = QuantumCircuit(3)
grover_circuit = init_state(grover_circuit, [0, 1, 2])
grover_circuit.draw("mpl")

oracle_qc = QuantumCircuit(3)
oracle_qc.cz(0, 1)
oracle_qc.cz(0, 2)
oracle_gate = oracle_qc.to_gate()   
oracle_gate.name = "U$_\omega$"

def diffuser(nqubits):
    qc = QuantumCircuit(nqubits)
    # Apply transformation |s> -> |00..0> -> |11..1>
    for qubit in range(nqubits):
        qc.h(qubit)
        qc.x(qubit)

    # When these are combined, they function as a multi-controlled Z gate
    # A negative phase is added to |11..1> to flip the state
    qc.h(nqubits-1)
    qc.mct(list(range(nqubits-1)), nqubits-1)  # multi-controlled-toffoli
    qc.h(nqubits-1)

    # Apply transformation |11..1> -> |00..0> -> |s>
    for qubit in range(nqubits):
        qc.x(qubit)
        qc.h(qubit)
    # We will return the diffuser as a gate
    U_s = qc.to_gate()
    U_s.name = "U$_s$"
    return U_s

num_qubits = 3
grover_circuit = QuantumCircuit(num_qubits)
grover_circuit = init_state(grover_circuit, [0, 1, 2])
grover_circuit.barrier()
grover_circuit.append(oracle_gate, [0, 1, 2])
grover_circuit.barrier()
grover_circuit.append(diffuser(num_qubits), [0, 1, 2])
grover_circuit.measure_all()
grover_circuit.draw("mpl")

qasm_sim = Aer.get_backend('qasm_simulator')
transpiled_grover_circuit = transpile(grover_circuit, qasm_sim)
results = qasm_sim.run(transpiled_grover_circuit).result()
counts = results.get_counts()
plot_histogram(counts)

backend = least_busy(provider.backends(filters=lambda x: x.configuration().n_qubits >= 3 and 
                                   not x.configuration().simulator and x.status().operational==True))
print("least busy backend: ", backend)

# Run our circuit on the least busy backend. Monitor the execution of the job in the queue
from qiskit.tools.monitor import job_monitor
transpiled_grover_circuit = transpile(grover_circuit, device, optimization_level=3)
job = device.run(transpiled_grover_circuit)
job_monitor(job, interval=2)

# Get the results from the computation
results = job.result()
answer = results.get_counts(grover_circuit)
plot_histogram(answer)