import qiskit
import numpy as np
from qiskit import(
    IBMQ, QuantumCircuit, ClassicalRegister, QuantumRegister, execute,
    QuantumCircuit,
    execute,
    Aer)
from qiskit.visualization import plot_histogram, plot_state_city


def increment_gate(circuit, qpos, qcoin):
    n = len(qpos)
    for i in range(n):
        circuit.mct(qcoin[:]+qpos[i+1:], qpos[i], None, mode='noancilla')

def decrement_gate(circuit, qpos, qcoin):
    n = len(qpos)
    for i in range(n):
        if i+1 < n: circuit.x(qpos[i+1:])
        circuit.mct(qcoin[:]+qpos[i+1:], qpos[i], None, mode='noancilla')
        if i+1 < n: circuit.x(qpos[i+1:])
    
def step(circuit, qpos, qcoin):
    circuit.h(qcoin)
    circuit.barrier()
    # y operations
    increment_gate(circuit, qpos[len(qpos)//2:], qcoin)
    circuit.x(qcoin[0])
    decrement_gate(circuit, qpos[len(qpos)//2:], qcoin)
    # x operations
    circuit.x(qcoin)
    increment_gate(circuit, qpos[:len(qpos)//2], qcoin)
    circuit.x(qcoin[0])
    decrement_gate(circuit, qpos[:len(qpos)//2:], qcoin)
    circuit.barrier()

simulator = Aer.get_backend('qasm_simulator')

n=3

qpos = QuantumRegister(2*n,'qc')
qcoin = QuantumRegister(2,'qanc')

cpos = ClassicalRegister(2*n,'cr')

circuit = QuantumCircuit(qpos, qcoin, cpos)

step(circuit, qpos, qcoin)

# # Map the quantum measurement to the classical bits
circuit.measure(qpos,cpos)

# # Execute the circuit on the qasm simulator
job = execute(circuit, simulator, shots=1000)

# # Grab results from the job
result = job.result()

# # Returns counts
counts = result.get_counts(circuit)
print("\nTotal count for 00 and 11 are:",counts)

# Draw the circuit
# circuit.draw()

# Plot a histogram


plot_histogram(counts)



