# Edit this example, then press Run. Reset restores the published version.

def require(condition, message):
    if not condition:
        raise AssertionError(message)


def add_vectors(vectors):
    return tuple(map(sum, zip(*vectors)))


def refinement():
    x = tuple(range(1, 9))
    coarse = tuple(x[r::2] for r in range(2))
    fine = tuple(x[r::4] for r in range(4))
    # Interleave by original addresses. No padding or boundary extension.
    rebuilt = tuple(fine[i % 4][i // 4] for i in range(len(x)))
    lifted = tuple(tuple(v if i % 4 == r else 0 for i, v in enumerate(x))
                   for r in range(4))
    for r in range(2):
        require(add_vectors((lifted[r], lifted[r+2])) ==
                tuple(v if i % 2 == r else 0 for i, v in enumerate(x)),
                'Coarse packet differs from its fine children')
    kept = add_vectors((lifted[0], lifted[1], lifted[3]))
    residual = tuple(a-b for a, b in zip(x, kept))
    energy = sum(v*v for v in residual)
    require(rebuilt == x, 'Interleaving failed')
    require(residual == lifted[2] and energy == 58, 'Discarded-packet control failed')
    return '\n'.join([
        f'Input: {x}', f'Two packets: {coarse}', f'Four packets: {fine}',
        f'Interleaved: {rebuilt}', f'Without remainder 2: {kept}',
        f'Residual: {residual}', f'Squared residual norm: {energy}',
        'PASS: refinement',
    ])


print(refinement())
