!pip install qiskit
from qiskit import *
from qiskit.tools.jupyter import *
from qiskit.visualization import *
import matplotlib.pyplot as plotter
import numpy as np
from IPython.display import display, Math, Latex
import qiskit.quantum_info as qi
%matplotlib inline
# Loading your IBM Q account(s)
provider = IBMQ.load_account()

def run_circuit(qc):
    backend = Aer.get_backend('qasm_simulator') # we choose the simulator as our backend
    result = execute(qc, backend, shots = 200000).result() # we run the simulation
    counts = result.get_counts() # we get the counts
    return counts

def qft_rotations(circuit, n):
    """Performs qft on the first n qubits in circuit (without swaps)"""
    if n == 0:
        return circuit
    n -= 1
    circuit.h(n)
    for qubit in range(n):
        circuit.cu1(np.pi/2**(n-qubit), qubit, n)
    # At the end of our function, we call the same function again on
    # the next qubits (we reduced n by one earlier in the function)
    qft_rotations(circuit, n)
def swap_registers(circuit, n):
    for qubit in range(n//2):
        circuit.swap(qubit, n-qubit-1)
    return circuit

def qft(circuit, n):
    """QFT on the first n qubits in circuit"""
    qft_rotations(circuit, n)
    
def inverse_qft(circuit, n):
    """Does the inverse QFT on the first n qubits in circuit"""
    # First we create a QFT circuit of the correct size:
    qft_circ = qft(QuantumCircuit(n), n)
    # Then we take the inverse of this circuit
    invqft_circ = qft_circ.inverse()
    # And add it to the first n qubits in our existing circuit
    circuit.append(invqft_circ, circuit.qubits[:n])
    return circuit.decompose() # .decompose() allows us to see the individual gates

    swap_registers(circuit, n)
    return circuit

# Basically change the values of n starting from 1,2(you know which aren't I),3,... We will start with 3
a = 0
n = 3
while a==0:
    c = ClassicalRegister(5)
    q = QuantumRegister(5)
    qc = QuantumCircuit(q,c)
    for i in range(n):
        qft(qc,5)
    qc.measure(range(5),range(5))
    counts = run_circuit(qc)
    if len(counts.keys()) == 1:
         if '00000' in counts.keys():
            a=1
            print(n)
    n = n+1

# Actually due to qiskit using reverse order for bit strings sometimes produces weird results when it comes to such matrices repeatedly.
# Nevertheless, you can search up on the internet for QFT matrix and you can calculate that QFT^4 indeed equals I.
    


# The matrix can be easily solved theoretically and can be found on the internet, Here we will get the matrix according to the qiskit nomenclature.

qc = QuantumCircuit(2)
qft(qc, 2)
qft(qc, 2)
with np.printoptions(precision=3, suppress=True):
    print(qi.Operator(qc).data)


# The required function. Also recall that T^2 = S, S^2 = Z.
def Modulo_increment(qc): # 4 bit circuit where q3 is MSB
    qft(qc,4)
    qc.rz(np.pi/8,0)
    qc.t(1)
    qc.s(2)
    qc.z(3)
    inverse_qft(qc,4)
    return qc

# Then you can check for different values.