import cirq
import numpy as np

def create_circuit():
    q_photon = cirq.LineQubit(0)
    q_which_path = cirq.LineQubit(1)
    q_idler = cirq.LineQubit(2)
    
    circuit = cirq.Circuit()
    circuit.append(cirq.H(q_photon))
    circuit.append(cirq.CNOT(q_photon, q_which_path))
    circuit.append(cirq.S(q_photon))
    circuit.append(cirq.CNOT(q_which_path, q_idler))
    circuit.append(cirq.H(q_photon))
    
    return circuit

def simulate_and_analyze():
    circuit = create_circuit()
    simulator = cirq.Simulator()
    result = simulator.simulate(circuit)
    final_state = result.final_state_vector
    
    prob_photon_0_idler_0 = (np.abs(final_state[0])**2 + np.abs(final_state[4])**2) / (np.abs(final_state[0])**2 + np.abs(final_state[1])**2 + np.abs(final_state[4])**2 + np.abs(final_state[5])**2)
    prob_photon_0_idler_1 = (np.abs(final_state[2])**2 + np.abs(final_state[6])**2) / (np.abs(final_state[2])**2 + np.abs(final_state[3])**2 + np.abs(final_state[6])**2 + np.abs(final_state[7])**2)
    
    return prob_photon_0_idler_0, prob_photon_0_idler_1

def send_message(message):
    results = []
    for bit in message:
        prob_0_0, prob_0_1 = simulate_and_analyze()
        if bit == '1':
            # Măsurăm idler (decizie din "viitor")
            results.append(abs(prob_0_0 - prob_0_1) > 0.5)
        else:
            # Nu măsurăm idler
            results.append(abs(prob_0_0 - 0.5) < 0.1)
    return results

def receive_message(results):
    received_message = ''
    for result in results:
        if result:
            received_message += '1'
        else:
            received_message += '0'
    return received_message

# Generăm un octet aleator pentru test
import random
message_to_send = ''.join(random.choice('01') for _ in range(8))

sent_results = send_message(message_to_send)
received_message = receive_message(sent_results)

print(f"Mesaj trimis:   {message_to_send}")
print(f"Mesaj primit:   {received_message}")
print(f"Transmisie corectă: {message_to_send == received_message}")

# Convertim octetul în caractere ASCII pentru a vedea ce "informație" am transmis
ascii_char = chr(int(message_to_send, 2))
print(f"Caracterul ASCII corespunzător octetului trimis: '{ascii_char}'")