import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np

from qiskit import IBMQ, BasicAer
from qiskit.providers.ibmq import least_busy
from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister, execute
from qiskit.quantum_info import Statevector
from qiskit.visualization import plot_state_qsphere
from qiskit.visualization import plot_histogram
from qiskit.tools.monitor import job_monitor

from qiskit.tools.visualization import plot_histogram
from IPython.display import display, Math, Latex

#define a 1 qubit state |0>
sv = Statevector.from_label('0')
print('State_0  |x> = ', sv.data)

#build a circuit with the H gate
mycircuit = QuantumCircuit(1)
mycircuit.h(0)

#apply the circuit into |x>
sv = sv.evolve(mycircuit)


print('State_1 H|x> = ', sv.data)
mycircuit.draw('mpl')

'''
OUR FUNCTION F IS DEFINED AS
                n = 2
                f(0, 0) = 0
                f(0, 1) = 1
                f(1, 0) = 1
                f(1, 1) = 1
'''
#input size
n = 2

#initialize qubits and measurement bits
input_qubits = QuantumRegister(n+1)
output_bits = ClassicalRegister(n)

#create circuit
my_circuit = QuantumCircuit(input_qubits, output_bits)

#apply X on the last qubit
my_circuit.x(n)

#apply Hadamard on all qubits
my_circuit.h(range(n+1))

my_circuit.barrier()

#Apply Uf, these CNOT gates will mark the desired |x_i>
my_circuit.cx(0, 1)
my_circuit.cx(1, 2)
my_circuit.cx(0, 1)

my_circuit.barrier()

#apply Hadamard on all qubits
my_circuit.h(range(n+1))

my_circuit.measure(range(n), range(n))


#Backend classical simulation
backend = BasicAer.get_backend('qasm_simulator')
atp = 1024
res = execute(my_circuit, backend=backend, shots=atp).result()
ans = res.get_counts()
my_circuit.draw(output='mpl')

#Quantum Backend
#SOON#

plot_histogram(ans)

from qiskit import IBMQ
IBMQ.load_account()

provider = IBMQ.get_provider(group='open', project='main')
backend = provider.get_backend('ibmq_vigo')
job = execute(my_circuit, backend=backend)
result = job.result().get_counts()

plot_histogram(result)