# importing Qiskit
from qiskit import IBMQ, Aer
from qiskit.providers.ibmq import least_busy
from qiskit import QuantumCircuit, transpile

# import basic plot tools
from qiskit.visualization import plot_histogram
from qiskit_textbook.tools import simon_oracle

b = '110'

n = len(b)
simon_circuit = QuantumCircuit(n*2, n)

# Apply Hadamard gates before querying the oracle
simon_circuit.h(range(n))    
    
# Apply barrier for visual separation
simon_circuit.barrier()

simon_circuit = simon_circuit.compose(simon_oracle(b))

# Apply barrier for visual separation
simon_circuit.barrier()

# Apply Hadamard gates to the input register
simon_circuit.h(range(n))

# Measure qubits
simon_circuit.measure(range(n), range(n))
simon_circuit.draw("mpl")

# use local simulator
aer_sim = Aer.get_backend('aer_simulator')
results = aer_sim.run(simon_circuit).result()
counts = results.get_counts()
print(f"Measured output: {counts}")
plot_histogram(counts)

from qiskit import QuantumCircuit, Aer, transpile, assemble
from qiskit.visualization import plot_histogram


# Function to create Simon's oracle for a given hidden string 's'
def simon_oracle(s):
    n = len(s)
    oracle_circuit = QuantumCircuit(n*2, n)
    
    # Apply CNOT gates according to the hidden string 's'
    for qubit in range(n):
        if s[qubit] == '1':
            oracle_circuit.cx(qubit, n + qubit)
    
    return oracle_circuit

# Hidden string 'b'
b = '1101'

# Number of qubits
n = len(b)

# Create a quantum circuit
simon_circuit = QuantumCircuit(n*2, n)

# Apply Hadamard gates to the first n qubits
simon_circuit.h(range(n))

# Apply a barrier for visual separation
simon_circuit.barrier()

# Compose the circuit with the Simon oracle for the given hidden string 'b'
simon_circuit = simon_circuit.compose(simon_oracle(b))

# Apply a barrier for visual separation
simon_circuit.barrier()

# Apply Hadamard gates to the first n qubits
simon_circuit.h(range(n))

# Measure the qubits
simon_circuit.measure(range(n), range(n))

# Visualize the circuit
simon_circuit.draw("mpl")


# Transpile the circuit for the simulator
simon_circuit = transpile(simon_circuit, Aer.get_backend('qasm_simulator'))

# Run the simulation
simulator = Aer.get_backend('qasm_simulator')
result = simulator.run(simon_circuit).result()

# Display the measured output
counts = result.get_counts(simon_circuit)
print(f"Measured output: {counts}")

# Plot the results
plot_histogram(counts)


