from qiskit import Aer, execute, QuantumCircuit, QuantumRegister
from qiskit.visualization import plot_bloch_multivector,plot_histogram

input_bit = QuantumRegister(1,'input')
output_bit = QuantumRegister(1,'output')
garbage_bit = QuantumRegister(1,'garbage')

Uf = QuantumCircuit(input_bit,output_bit,garbage_bit)
Uf.cx(input_bit,output_bit)
# Uf.draw('mpl',justify=None)

Vf = QuantumCircuit(input_bit,output_bit,garbage_bit)
Vf.cx(input_bit,garbage_bit)
Vf.cx(input_bit,output_bit)
# Vf.draw('mpl',justify=None)

qc = Uf + Vf.inverse()
# qc.draw('mpl')

final_output_bit = QuantumRegister(1,'final_output')

copy = QuantumCircuit(output_bit,final_output_bit)
copy.cx(output_bit,final_output_bit)

# copy.draw('mpl',justify='None')

(Vf.inverse() + copy + Vf).draw(output='mpl',justify='None')

qc0 = QuantumCircuit(input_bit,output_bit,garbage_bit,final_output_bit)
qc0 = qc0 + Vf.inverse() + copy + Vf

qc0.draw('mpl',justify='none')

qasm_sim = Aer.get_backend('qasm_simulator')
qc0.measure_all()
result = execute(qc0,backend=qasm_sim).result()
counts = result.get_counts()
plot_histogram(counts)

qc1 = QuantumCircuit(input_bit,output_bit,garbage_bit,final_output_bit)
qc1.x(0)
qc1 = qc1 + Vf.inverse() + copy + Vf

qc1.draw('mpl',justify='none')

qc1.measure_all()
result = execute(qc1,backend=qasm_sim).result()
counts = result.get_counts()
plot_histogram(counts)

qc = QuantumCircuit(input_bit,output_bit,garbage_bit,final_output_bit)
qc.x(1)
qc = qc + Vf.inverse() + copy + Vf
qc = qc.reverse_bits()

qc.draw('mpl',justify='none')

qc.measure_all()
result = execute(qc,backend=qasm_sim).result()
counts = result.get_counts()
plot_histogram(counts)

qc = QuantumCircuit(input_bit,output_bit,garbage_bit,final_output_bit)
qc.x([0,1])
qc = qc + Vf.inverse() + copy + Vf
qc = qc.reverse_bits()

qc.draw('mpl',justify='none')

qc.measure_all()
result = execute(qc,backend=qasm_sim).result()
counts = result.get_counts()
plot_histogram(counts)

import qiskit
qiskit.__qiskit_version__