def square_roots(a,b,c):
    # we iteratively calculate the expression with many square roots
    # we start with c and continue with b and a
    result = c**0.5 # square root of c
    result = 2 * result # 2*sqrt(c)
    result = result + b # b + 2*sqrt(c)
    result = result**0.5 # square root
    result = a**0.5 - result
    return result

quantum_state =[
    square_roots(3,5,6)**(-1),
    square_roots(3,7,12)**(-1),
    square_roots(5,13,40)**(-1),
    square_roots(7,15,56)**(-1),
] # this is our quantum state

# print the quantum state
print(quantum_state)

print()
print("The probability of observing the states 00, 01, 10, 11:")
total_probability = 0
for i in range(len(quantum_state)):
    current_probability = quantum_state[i]**2 # square of the amplitude
    print(current_probability)
    total_probability = total_probability + current_probability

print()
print("total probability is",total_probability)

# import all necessary objects and methods for quantum circuits
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit, execute, Aer
# import randrange for random choices
from random import randrange

number_of_qubit = 5

# define a quantum register with 5 qubits
qreg =  QuantumRegister(number_of_qubit)

# define a classical register with 5 bits
creg = ClassicalRegister(number_of_qubit)

# define our quantum circuit
mycircuit = QuantumCircuit(qreg,creg)

# apply h-gate to all qubits
for i in range(number_of_qubit):
    mycircuit.h(qreg[i])

# apply z-gate to randomly picked qubits
for i in range(number_of_qubit):
    if randrange(2) == 0: # the qubit with index i is picked to apply z-gate
        mycircuit.z(qreg[i])
        
# apply h-gate to all qubits
for i in range(number_of_qubit):
    mycircuit.h(qreg[i])
    
    
# measure all qubits
mycircuit.measure(qreg,creg)

print("Everything looks fine, let's continue ...")

# draw the circuit

mycircuit.draw()

# execute the circuit 1000 times in the local simulator

job = execute(mycircuit,Aer.get_backend('qasm_simulator'),shots=1000)
counts = job.result().get_counts(mycircuit)
for outcome in counts: # print the reverse of the outcome
    reverse_outcome = ''
    for i in outcome:
        reverse_outcome = i + reverse_outcome
    print(reverse_outcome,"is observed",counts[outcome],"times")