import random


def crossover(a, b, verbose=False):
    """
    Cruza dos redes neuronales y regresa los cromosomas resultantes:

    Parámetros
    ----------
    a, b : NeuralNet
        Redes neuronales a cruzar

    Salida
    ------
    a_enc, b_enc : NeuralNet
        Redes producto del crossover de un solo punto de  `a` y `b`. Están
        codificadas para facilitar mutación.

    Notas
    -----
    Esta función implementa crossover de un sólo punto. Si por ejemplo tenemos
    los cromosomas [AAAAAA, BBBBBB], los pasos que sigue son:

    1. Escoge un índice aleatorio, por ejemplo 2.
    2. Parte los cromosomas en este índice, y los intercambia:

    AAAAAA --> AA AAAA --> BB AAAA --> BBAAAA
    BBBBBB --> BB BBBB --> AA BBBB --> AABBBB

    Los cromosomas intercambiados son dos hijos nuevos.
    """
    # Codificamos las redes de ambos individuos en un vector unidimensional
    a_enc = a.encode()
    b_enc = b.encode()

    # Crossover de un solo punto: escogemos un índice aleatorio donde partir
    # los vectores
    split = random.randint(0, len(a_enc)-1)
    split_a = a_enc[:split].copy()
    split_b = b_enc[:split].copy()

    # Intercambiamos los 
    a_enc[:split] = split_b
    b_enc[:split] = split_a

    if verbose:
        print("Split index:", split)

    return a_enc, b_enc