from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, execute, Aer
from qiskit.visualization import plot_state_qsphere, plot_histogram

# We create a Quantum Register with 3 qubits.
q = QuantumRegister(3, 'qubit')

# We create a Classical Register with 3 bits.
c = ClassicalRegister(3, 'Classical bit')

# We create a Quantum Circuit
qc = QuantumCircuit(q, c)


# We add x gate to the first qubit
qc.x(q[0])
qc.barrier()
qc.draw(output='mpl')

qc.h(q[1])
qc.cx(q[1], q[2])
qc.barrier()
qc.draw(output='mpl')

qc.cx(q[0], q[1])
qc.h(0)
qc.barrier()
qc.measure(0,0)
qc.measure(1,1)
qc.barrier()
qc.draw(output='mpl')

from math import pi
qc.crx(pi, q[1], q[2]).c_if(c, 1)
qc.crz(pi, q[0], q[2]).c_if(c, 1)

qc.draw(output='mpl')

# We execute the quantum circuit on a statevector simulator backend
backend = Aer.get_backend('statevector_simulator')
result = execute(qc, backend).result()
statevector = result.get_statevector(qc)
plot_state_qsphere(statevector, show_state_phases = True, use_degrees = True)

from qiskit import IBMQ
from qiskit.providers.ibmq import least_busy

# Replace 'MY_API_TOKEN' with your actual API token
IBMQ.save_account('API_TOKEN', overwrite=True)


# We get the least busy IBM Quantum device
provider = IBMQ.get_provider(hub='ibm-q')
backend = least_busy(provider.backends(filters=lambda x: x.configuration().n_qubits >= 3 and not x.configuration().simulator and x.status().operational==True))

# We print the name of the least busy backend
print("Least busy backend:", backend.name())

import time
from qiskit.tools.monitor import job_monitor

# We execute the circuit on the least busy backend. Monitor the execution of the job in the queue
backend = provider.get_backend('ibmq_belem')

# We execute the circuit on the backend
start_time = time.time()
job_exp = execute(qc, backend=backend, shots=1024)
job_monitor(job_exp, interval=2)
result_exp = job_exp.result()
counts_exp = result_exp.get_counts(qc)
end_time = time.time()

# We calculate the time taken in minutes and seconds
time_taken = end_time - start_time
minutes, seconds = divmod(time_taken, 60)

# We print the results and the time it took to run the code
print("Counts:", counts_exp)
print("Time taken: {} minutes and {:.2f} seconds".format(int(minutes), seconds))

plot_histogram(counts_exp)