!pip install qiskit

#superpositon, entanglement and interference
my_list=[1,3,5,2,4,9,5,8,0,7,6]

#eracle is the black box at the disposal->we can call it and ask whether this number is a whinner or not
def the_oracle(my_input):
  winner=7
  if my_input is winner:
    response=True
  else:
    response=False
  return response

for index, trial_number in enumerate(my_list):
  if the_oracle(trial_number)==True:
    print('winner found at index %i'%index)
    print('%i calls at the oracle used'%(index+1))

#oracle works here by flipping the sign of the input of the winner
#controlled Z gate -> |11> -> [CZ] -> -|11>
#amplitute amplification ->reflection operator

#Grovvers diffusion operator-> oracle+ Reflection
from qiskit import *
import matplotlib.pyplot as py
import numpy as np

#define oracle circuit
oracle = QuantumCircuit(2,name='oracle')
oracle.cz(0,1)
oracle.to_gate()#make oracle into its own gate

oracle.draw(initial_state = True)

#preparing a supepositon state of all the gates by applying the handmard gate on each one of them
#in this way each uery xould be simuntaneousky reached oracle
backend=Aer.get_backend('statevector_simulator')
# statevector_simulator backend is selected, which allows for simulation of the quantum state vector of the circuit.
grover_circ=QuantumCircuit(2,2)
#The first argument 2 specifies the number of qubits in the quantum registers, and the second argument 2 specifies the number of classical bits in the classical registers.
grover_circ.h([0,1])
#This line applies the Hadamard gate (H gate) to qubits 0 and 1 in the grover_circ circuit.
grover_circ.append(oracle,[0,1])
grover_circ.draw(initial_state = True)

job= execute(grover_circ,backend)
result=job.result()

sv=result.get_statevector()
np.around(sv,2)

#square the state vectors to get back the probabilities
reflection = QuantumCircuit(2,name="reflection")
reflection.h([0,1])
reflection.z([0,1])
reflection.cz(0,1)
reflection.h([0,1])
reflection.to_gate()

reflection.draw(initial_state = True)

backend=Aer.get_backend('statevector_simulator')
# statevector_simulator backend is selected, which allows for simulation of the quantum state vector of the circuit.
grover_circ=QuantumCircuit(2,2)
#The first argument 2 specifies the number of qubits in the quantum registers, and the second argument 2 specifies the number of classical bits in the classical registers.
grover_circ.h([0,1])
#This line applies the Hadamard gate (H gate) to qubits 0 and 1 in the grover_circ circuit.
grover_circ.append(oracle,[0,1])
grover_circ.append(reflection,[0,1])
grover_circ.measure([0,1],[0,1])

grover_circ.draw(initial_state = True)

job= execute(grover_circ,backend,shots=1)
result=job.result()
result.get_counts()

