# A407_Llueca
import random as r 
LIST_LENGTH = 400

## 1. Residual Coding/Decoding
def RC(X,f):
    '''
    Residual coding of the numerical list X 
    using the function f
    '''
    Y = []
    for i,x in enumerate(X):
        v = f(i+1)
        Y += [(x - v)]
    return Y

def RD(Y,f):
    '''
    Residual decoding of the list of residuals Y using the function f
    '''
    X = []
    for i, x in enumerate(Y):
        v = f(i+1)
        X += [(v + x)]
    return X

# Test
X = []
for i in range(LIST_LENGTH):
    X.append(r.randint(1, 999))

def f(x):
    return x*x - x + 41
print('Residual Coding')
print('X: ',X)
print('f(x) = x^2 - x + 41')
Y = RC(X,f)
print('Y = RC(X,f): ',Y)
X2 = RD(Y,f)
print('X2 = RD(Y,f): ', X2)
if X == X2:
    print('correct encoding/decoding!')
else:
    print('error ocurred during encoding/decoding')

## 2. Predictive Coding/Decoding
# y_j = x_j - (x_{j-2} + x_{j-1})/2
# x_1 = x_2 = 0
def PC(X):
	Y = [0,0]
	for i in range(2,len(X)): 
		yi = X[i] - ((X[i-2] + X[i-1]) / 2)
		Y.append(yi)
	return Y

def PD(Y):
    X = [0,0]
    for i in range(2,len(Y)):
        xi = Y[i] + ((X[i-2] + X[i-1]) / 2)
        X.append(xi)
    return X



X = [0,0]
for i in range(LIST_LENGTH):
    X.append(r.randint(1, 999))
Y = PC(X)
print('\nPredicitve Coding')
print('X: ', X)
print('Y = PC(X): ', Y)
X2 = PD(Y)
print ('X2 = PD(Y): ', X2)
if X == X2:
    print('correct encoding/decoding!')
else:
    print('error ocurred during encoding/decoding')






