pip install qiskit

# Useful packages for the next gates experiments
import numpy as np
from qiskit import QuantumCircuit, QuantumRegister
from qiskit import execute
from qiskit.tools.visualization import circuit_drawer
from qiskit import Aer
backend = Aer.get_backend('unitary_simulator')


# Pauli X : bit-flip gate
q = QuantumRegister(1)
qc = QuantumCircuit(q)
qc.x(q)
im = circuit_drawer(qc)
im.save("GateX.png", "PNG")
job = execute(qc, backend)
print(np.round(job.result().get_data(qc)['unitary'], 3))

# Pauli Y : bit and phase-flip gate
q = QuantumRegister(1)
qc = QuantumCircuit(q)
qc.y(q)
im = circuit_drawer(qc)
im.save("GateY.png", "PNG")
job = execute(qc, backend)
print(np.round(job.result().get_data(qc)['unitary'], 3))

# Pauli Z : phase-flip gate
q = QuantumRegister(1)
qc = QuantumCircuit(q)
qc.z(q)
im = circuit_drawer(qc)
im.save("GateZ.png", "PNG")
job = execute(qc, backend)
print(np.round(job.result().get_data(qc)['unitary'], 3))

# Clifford Hadamard gate
q = QuantumRegister(1)
qc = QuantumCircuit(q)
qc.h(q)
im = circuit_drawer(qc)
im.save("GateH.png", "PNG")
job = execute(qc, backend)
print(np.round(job.result().get_data(qc)['unitary'], 3))

# Clifford S gate
q = QuantumRegister(1)
qc = QuantumCircuit(q)
qc.s(q)
im = circuit_drawer(qc)
im.save("GateS.png", "PNG")
job = execute(qc, backend)
print(np.round(job.result().get_data(qc)['unitary'], 3))

# Clifford T gate
q = QuantumRegister(1)
qc = QuantumCircuit(q)
qc.t(q)
im = circuit_drawer(qc)
im.save("GateT.png", "PNG")
job = execute(qc, backend)
print(np.round(job.result().get_data(qc)['unitary'], 3))

# Pauli Controlled-X (or, controlled-NOT) gate
q = QuantumRegister(2)
qc = QuantumCircuit(q)
qc.cx(q)
im = circuit_drawer(qc)
im.save("GateCX.png", "PNG")
job = execute(qc, backend)
print(np.round(job.result().get_data(qc)['unitary'], 3))

# Pauli Controlled Z (or, controlled Phase) gate
q = QuantumRegister(2)
qc = QuantumCircuit(q)
qc.cz(q)
im = circuit_drawer(qc)
im.save("GateCZ.png", "PNG")
job = execute(qc, backend)
print(np.round(job.result().get_data(qc)['unitary'], 3))

# SWAP gate
q = QuantumRegister(2)
qc = QuantumCircuit(q)
qc.swap(q)
im = circuit_drawer(qc)
im.save("GateSWAP.png", "PNG")
job = execute(qc, backend)
print(np.round(job.result().get_data(qc)['unitary'], 3))

# Toffoli gate (ccx gate)
q = QuantumRegister(3)
qc = QuantumCircuit(q)
qc.ccx(q)
im = circuit_drawer(qc)
im.save("GateCCX.png", "PNG")
job = execute(qc, backend)
print(np.round(job.result().get_data(qc)['unitary'], 3))

from qiskit import ClassicalRegister, QuantumRegister
from qiskit import QuantumCircuit, execute
from qiskit.tools.visualization import plot_histogram, circuit_drawer
# Create a Quantum Register called "qr" with 2 qubits.
qr = QuantumRegister(2)
# Create a Classical Register called "cr" with 2 bits.
cr = ClassicalRegister(2)
# Create a Quantum Circuit called "qc" with qr and cr.
qc = QuantumCircuit(qr, cr)
# Add the H gate in the Qubit 1, putting this qubit in superposition.
qc.h(qr[1])
# Add the CX gate on control qubit 1 and target qubit 0, putting the qubits in a Bell state i.e entanglement.
qc.cx(qr[1], qr[0])
# Add a Measure gate to see the state.
qc.measure(qr, cr)
# Compile and execute the quantum program in the local simulator.
job_sim = execute(qc, "qasm_simulator")
stats_sim = job_sim.result().get_counts()
# Plot and print results.
plot_histogram(stats_sim)
print(stats_sim)
im = circuit_drawer(qc)
im.save("circuit.png", "PNG")

from qiskit import ClassicalRegister, QuantumRegister
from qiskit import QuantumCircuit, execute
from qiskit.tools.visualization import plot_histogram
import matplotlib.pyplot as plt
# 3 bitStrings, one for each symbol : )( 
#":" 00111010 "(" 00101000 ")" 00101001
# Create a Quantum Register called "qr" with 16 qubits.
qr = QuantumRegister(16)
# Create a Classical Register called "cr" with 16 bits.
cr = ClassicalRegister(16)
# Create a Quantum Circuit called "qc" with qr and cr.
qc = QuantumCircuit(qr, cr)
# Add the H gate in the 0 Qubit, putting the qubit in superposition.
qc.h(qr[0])
qc.x(qr[3])
qc.x(qr[5])
qc.x(qr[9])
qc.x(qr[11])
qc.x(qr[12])
qc.x(qr[13])
for j in range(16):
    qc.measure(qr[j], cr[j])
# Compile and execute the quantum program in the local simulator.
shots_sim = 128
job_sim = execute(qc, "qasm_simulator", shots=shots_sim)
stats_sim = job_sim.result().get_counts()
# Plot and print results.
plot_histogram(stats_sim)
print(stats_sim)
def plotSmiley (stats, shots):
    for bitString in stats:
        char = chr(int(bitString[0:8],2)) # 8 bits (left), convert to an ASCII character.
        char += chr(int(bitString[8:16],2)) # 8 bits (right), add it to the previous character.
        prob = stats[bitString]/shots # Fraction of shots the result occurred
        plt.annotate(char, (0.5,0.5), va="center", ha="center", color = (0,0,0,prob), size = 300) # Create plot.
    plt.axis("off")
    plt.show()
plotSmiley(stats_sim, shots_sim)

from qiskit import ClassicalRegister, QuantumRegister
from qiskit import QuantumCircuit, execute
# E.g. number 21 in binary.
number = "10101"
# Initializing the registers.
# Create a Quantum Register called "qr" with length number qubits.
qr = QuantumRegister(len(str(number)))
# Create a Classical Register called "cr" with length number bits.
cr = ClassicalRegister(len(str(number)))
# Create a Quantum Circuit called "qc" with qr and cr.
qc = QuantumCircuit(qr, cr)
# Setting up the registers using the value inputted.
for i in range(len(str(number))):
    if number[i] == "1":
       qc.x(qr[len(str(number)) - (i+1)]) #Flip the qubit from 0 to 1.
#Measure qubits and store results in classical register cr.
for i in range(len(str(number))):
    qc.measure(qr[i], cr[i])
# Compile and execute the quantum program in the local simulator.
job_sim = execute(qc, "qasm_simulator")
stats_sim = job_sim.result().get_counts()
# Print number.
print(stats_sim)

# Boolean binary string adder.
def rjust_lenght(s1, s2, fill='0'):
    l1, l2 = len(s1), len(s2)
    if l1 > l2:
        s2 = s2.rjust(l1, fill)
    elif l2 > l1:
        s1 = s1.rjust(l2, fill)
    return (s1, s2)
def get_input():
    bits_a = input('input your first binary string ')
    bits_b = input('input your second binary string ')
    return rjust_lenght(bits_a, bits_b)
def xor(bit_a, bit_b):
    A1 = bit_a and (not bit_b)
    A2 = (not bit_a) and bit_b
    return int(A1 or A2)
def half_adder(bit_a, bit_b):
    return (xor(bit_a, bit_b), bit_a and bit_b)
def full_adder(bit_a, bit_b, carry=0):
    sum1, carry1 = half_adder(bit_a, bit_b)
    sum2, carry2 = half_adder(sum1, carry)
    return (sum2, carry1 or carry2)
def binary_string_adder(bits_a, bits_b):
    carry = 0
    result = ''
    for i in range(len(bits_a)-1 , -1, -1):
        summ, carry = full_adder(int(bits_a[i]), int(bits_b[i]), carry)
        result += str(summ)
    result += str(carry)
    return result[::-1]
def main():
    bits_a, bits_b = get_input()
    print('1st string of bits is : {}, ({})'.format(bits_a, int(bits_a, 2)))
    print('2nd string of bits is : {}, ({})'.format(bits_b, int(bits_b, 2)))
    result = binary_string_adder(bits_a, bits_b)
    print('summarized is         : {}, ({})'.format(result, int(result, 2)))
if __name__ == '__main__':
    main()


from qiskit import ClassicalRegister, QuantumRegister
from qiskit import QuantumCircuit, execute
from qiskit.tools.visualization import circuit_drawer
# Initializing the registers.
# Create a Quantum Registers.
cin = QuantumRegister(1)
a = QuantumRegister(4)
b = QuantumRegister(4)
cout = QuantumRegister(1)
# Create a Classical Registers.
ans = ClassicalRegister(5)
# Create a Quantum Circuit called "qc".
qc = QuantumCircuit(cin, a, b, cout, ans)
# Set input states.
x = "0001" #1
y = "1111" #15
# Setting up the registers using the value inputted.
for i in range(len(str(x))):
    if x[i] == "1":
       qc.x(a[len(str(x)) - (i+1)]) #Flip the qubit from 0 to 1.
for i in range(len(str(y))):
    if y[i] == "1":
       qc.x(b[len(str(y)) - (i+1)]) #Flip the qubit from 0 to 1.
def majority(circ, a, b, c):
  circ.cx(c,b)
  circ.cx(c,a)
  circ.ccx(a,b,c)
def unmaj(circ, a, b, c):
  circ.ccx(a,b,c)
  circ.cx(c,a)
  circ.cx(a,b)
# Add a to b, storing result in b
majority(qc,cin[0],b[0],a[0])
majority(qc,a[0],b[1],a[1])
majority(qc,a[1],b[2],a[2])
majority(qc,a[2],b[3],a[3])
qc.cx(a[3],cout[0])
unmaj(qc,a[2],b[3],a[3])
unmaj(qc,a[1],b[2],a[2])
unmaj(qc,a[0],b[1],a[1])
unmaj(qc,cin[0],b[0],a[0])
# Measure qubits and store results.
for i in range(0, 4):
  qc.measure(b[i], ans[i])
qc.measure(cout[0], ans[4])
# Compile and execute the quantum program in the local simulator.
num_shots = 2 # Number of times to repeat measurement.
job = execute(qc, "qasm_simulator", shots=num_shots)
job_stats = job.result().get_counts()
# Print result number and circuit.
print(job_stats)
im = circuit_drawer(qc)
im.save("circuitSum.png", "PNG")

from qiskit import ClassicalRegister, QuantumRegister
from qiskit import QuantumCircuit, execute
from qiskit.tools.visualization import circuit_drawer
import numpy as np
n1 = '10011'
# E.g. number 19
n2 = '0011101'
# E.g. number 29
if len(str(n1)) > len(str(n2)):
     n = len(str(n1))
else:
     n = len(str(n2))
# Initializing the registers.
# Create a Quantum Registers called "qr1" and "qr2".
qr1 = QuantumRegister(n+1)
qr2 = QuantumRegister(n+1)
# The classical register.
cr = ClassicalRegister(n+1)
# Create a Quantum Circuit called "qc".
qc = QuantumCircuit(qr1, qr2, cr)
length1 = len(n1)
length2 = len(n2)
# Set same length.
if length2 > length1:
    n1,n2 = n2, n1
    length2, length1 = length1, length2
n2 = ("0")*(length1-length2) + n2
# Set registers qr1 and qr2 to hold the two numbers.
for i in range(len(str(n1))):
    if n1[i] == "1":
      qc.x(qr1[len(str(n1)) - (i+1)])
for i in range(len(str(n2))):
    if n2[i] == "1":
       qc.x(qr2[len(str(n2)) - (i+1)])
def qft(circ, q1, q2, n):
  # n-qubit QFT on q in circ.
  for i in range(0, n+1):
          qc.cu1(np.math.pi/float(2**(i)), q2[n-i], q1[n])
def invqft(circ, q, n):
    # Performs the inverse quantum Fourier transform.
    for i in range(0, n):
        qc.cu1(-np.math.pi/float(2**(n-i)), q[i], q[n])
    qc.h(q[n])
def input_state(circ, q, n):
    # n-qubit input state for QFT.
    qc.h(q[n])
    for i in range(0, n):
        qc.cu1(np.math.pi/float(2**(i+1)), q[n-(i+1)], q[n])
for i in range(0, n+1):
  input_state(qc, qr1, n-i)
qc.barrier()
for i in range(0, n+1):
  qft(qc, qr1, qr2, n-i)
qc.barrier()
for i in range(0, n+1):
  invqft(qc, qr1, i)
qc.barrier()
for i in range(0, n+1):
  qc.cx(qr1[i],qr2[i])
for i in range(0, n+1):
  qc.measure(qr1[i], cr[i])
# Compile and execute the quantum program in the local simulator.
num_shots = 2 # Number of times to repeat measurement.
job = execute(qc, "qasm_simulator", shots=num_shots)
job_stats = job.result().get_counts()
print(job_stats)
im = circuit_drawer(qc)
im.save("circuitAdderQFT.png", "PNG")


from qiskit import ClassicalRegister, QuantumRegister
from qiskit import QuantumCircuit, execute
from qiskit.tools.visualization import circuit_drawer
# Initializing the registers.
# Create a Quantum Registers.
cin = QuantumRegister(1)
a = QuantumRegister(2)
b = QuantumRegister(2)
cout = QuantumRegister(1)
# Create a Classical Registers.
ans = ClassicalRegister(3)
# Create a Quantum Circuit called "qc".
qc = QuantumCircuit(cin, a, b, cout, ans)
# Set input states.
x = "00" #0
y = "11" #3
# Setting up the registers using the value inputted.
for i in range(len(str(x))):
    if x[i] == "1":
       qc.x(a[len(str(x)) - (i+1)]) #Flip the qubit from 0 to 1.
for i in range(len(str(y))):
    if y[i] == "1":
       qc.x(b[len(str(y)) - (i+1)]) #Flip the qubit from 0 to 1.
# Add a to b, storing result in b
majority(qc,cin[0],b[0],a[0])
majority(qc,a[0],b[1],a[1])
qc.cx(a[1],cout[0])
unmaj(qc,a[0],b[1],a[1])
unmaj(qc,cin[0],b[0],a[0])
qc.cx(b[1],b[0])
qc.x(b[1])
# Measure qubits and store results.
for i in range(0, 1):
  qc.measure(b[i], ans[i])
qc.measure(cout[0], ans[1])
# Compile and execute the quantum program in the local simulator.
num_shots = 2 # Number of times to repeat measurement.
job = execute(qc, "qasm_simulator", shots=num_shots)
job_stats = job.result().get_counts()
# Print result number and circuit.
print(job_stats)
im = circuit_drawer(qc)
im.save("circuitAverage.png", "PNG")

import matplotlib.pyplot as plt
import numpy as np
from qiskit import ClassicalRegister, QuantumRegister
from qiskit import QuantumCircuit, execute
from qiskit.tools.visualization import plot_histogram, circuit_drawer
n = 3
sat_formula = [[1,2,-3],[-1,-2,-3],[1,-2,3]]
f_in = QuantumRegister(n)
f_out = QuantumRegister(1)
aux = QuantumRegister(len(sat_formula)+1)
ans = ClassicalRegister(n)
qc = QuantumCircuit(f_in, f_out, aux, ans)
# Initializes all of the qbits.
def input_state(circuit, f_in, f_out, n):
  for j in range(n):
    circuit.h(f_in[j])
  circuit.x(f_out)
  circuit.h(f_out)
# The back box U function (Oracle).
def black_box_u_f(circuit, f_in, f_out, aux, n, sat_formula):
  num_claus = len(sat_formula)
  for(k,claus) in enumerate(sat_formula):
    for literal in claus:
      if literal > 0:
        circuit.cx(f_in[literal-1],aux[k])
      else:
        circuit.x(f_in[-literal-1])
        circuit.cx(f_in[-literal-1],aux[k])
    circuit.ccx(f_in[0],f_in[1],aux[num_claus])
    circuit.ccx(f_in[2],aux[num_claus],aux[k])
    circuit.ccx(f_in[0],f_in[1],aux[num_claus])
    for literal in claus:
      if literal < 0:
        circuit.x(f_in[-literal-1])
  if(num_claus == 1):
    circuit.cx(aux[0], f_out[0])
  elif(num_claus == 2):
    circuit.ccx(aux[0],aux[1],f_out[0])
  elif(num_claus == 3):
    circuit.ccx(aux[0], aux[1], aux[num_claus])
    circuit.ccx(aux[2], aux[num_claus], f_out[0])
    circuit.ccx(aux[0], aux[1], aux[num_claus])
  else:
    raise ValueError('Apenas 3 clausulas pf :)')
  for(k,claus) in enumerate(sat_formula):
    for literal in claus:
      if literal > 0:
        circuit.cx(f_in[literal-1],aux[k])
      else:
        circuit.x(f_in[-literal-1])
        circuit.cx(f_in[-literal-1],aux[k])
    circuit.ccx(f_in[0], f_in[1], aux[num_claus])
    circuit.ccx(f_in[2], aux[num_claus], aux[k])
    circuit.ccx(f_in[0], f_in[1], aux[num_claus])
    for literal in claus:
      if literal < 0:
        circuit.x(f_in[-literal-1])
# iInverts the qbit that was affected by the Oracle function.
def inversion_about_average(circuit,f_in,n):
  for j in range(n):
    circuit.h(f_in[j])
  for j in range(n):
    circuit.x(f_in[j])
  n_controlled_z(circuit, [f_in[j] for j in range(n-1)], f_in[n-1])
  for j in range(n):
    circuit.x(f_in[j])
  for j in range(n):
    circuit.h(f_in[j])
def n_controlled_z(circuit,controls,target):
  if(len(controls) > 2):
    raise ValueError('erro de control')
  elif(len(controls) == 1):
    circuit.h(target)
    circuit.cx(controls[0],target)
    circuit.h(target)
  elif(len(controls) == 2):
    circuit.h(target)
    circuit.ccx(controls[0],controls[1],target)
    circuit.h(target)
input_state(qc,f_in,f_out,n)
black_box_u_f(qc,f_in,f_out,aux,n,sat_formula)
inversion_about_average(qc,f_in,n)
black_box_u_f(qc,f_in,f_out,aux,n,sat_formula)
inversion_about_average(qc,f_in,n)
for j in range(n):
  qc.measure(f_out[0],ans[j])
# Compile and execute the quantum program in the local simulator.
job_sim = execute(qc, "qasm_simulator")
stats_sim = job_sim.result().get_counts()
# Plot and print results.
print(stats_sim)
plot_histogram(stats_sim)
im = circuit_drawer(qc)
im.save("circuitGrover.pdf", "PDF")
