Loros Yanee es una admiradora de aves. Desde que leyó sobre IP over Avian Carriers (IPoAC), ella ha pasado mucho tiempo entrenando una bandada de loros inteligentes para enviar mensajes a largas distancias. El sueño de Yanee es usar sus aves para enviar un mensaje M a un lugar muy muy lejano. Su mensaje M es una secuencia de N enteros (no necesariamente distintos), cada uno entre 0 y 255, inclusive. Yanee mantiene K loros especialmente entrenados. Todos los loros se ven igual; Yanee no puede diferenciarlos. Cada loro puede recordar un solo entero entre 0 y R, inclusive. Anteriormente, ella probó un sistema sencillo: para enviar un mensaje, Yanee soltaba cuidadosamente a las aves de la jaula uno por uno. Antes de que cada ave volara en el aire, ella le enseñaba un número de la secuencia en orden. Desafortunadamente, este sistema no funcionó. Eventualmente, todas las aves llegaron al destino, pero no llegaron necesariamente en el orden en que habían partido. Con este sistema, Yanee podía recuperar todos los números que ella envió, pero no era capaz de ponerlos en el orden correcto. Para cumplir su sueño, Yanee necesitará un sistema mejor, y para eso necesita de su ayuda. Dado un mensaje M, ella planea soltar a las aves una por una como antes. Ella necesita que usted escriba un programa que ejecute dos operaciones separadas: Primero, su programa debe leer un mensaje M y transformarlo en una secuencia de a lo más K enteros entre 0 y R que ella enseñará a las aves. Segundo, su programa debe ser capaz de leer la lista entre 0 y R recibida cuando las aves llegan a su destino, y luego transformarla de vuelta al mensaje original M. Usted puede suponer que todos los loros siempre llegan al destino, y que cada uno de ellos recuerda el número que le fue asignado. Yanee le recuerda una vez más que los loros pueden llegar en cualquier orden. Observe que Yanee tiene únicamente K loros, por lo tanto la secuencia de enteros entre 0 y R que usted produce deberá contener a lo sumo K enteros. Su tarea Escriba dos procedimientos separados. Uno de ellos debe ser usado por el remitente (codificador) y el otro por el destinatario (decodificador). Página 1 de 6
El proceso en general es mostrado en la siguiente figura: Original Codificado Mezclado de Salida Codificador Mezclador Decodificador (Debe ser igual a M) Los dos procedimientos que usted debe escribir son: Procedimiento encode(n,m) que recibe los siguientes parámetros: N la longitud del mensaje. M un arreglo unidimensional de N enteros representando el mensaje. Usted puede asumir que 0 M[i] 255, para 0 i < N. Este procedimiento debe codificar el mensaje M en una secuencia de enteros entre 0 y R, inclusive, que debe ser enviado usando los loros. Para reportar esta secuencia, su procedimiento encode debe llamar el procedimiento send(a) para cada entero a que usted quiere enseñar a una de las aves. Procedimiento decode(n,l,x) que toma los siguientes parámetros: N la longitud del mensaje original. L la longitud del mensaje recibido (el numero de aves enviadas). X un arreglo unidimensional de L enteros representado los números recibidos. Los números X[i] para 0 <= i < L son precisamente los números que su procedimiento encode produjo, pero posiblemente reorganizados en un orden diferente. Este procedimiento debe recuperar el mensaje original. Para reportarlo, su procedimiento decode debe llamar el procedimiento output(b) para cada entero b en el mensaje decodificado, en el orden correcto. Note que R y K no se reciben como parámetros de entrada por favor mirar la descripción de las subtareas posteriormente. Para resolver correctamente una subtarea dada, sus procedimientos deben satisfacer las siguientes condiciones: Todos los enteros enviados por su procedimiento encode deben estar en el rango especificado en la subtarea. El número de veces que su procedimiento encode llama al procedimiento send no debe exceder el límite K especificado en la subtarea. Por favor, note que K depende en la longitud del mensaje. Página 2 de 6
El procedimiento decode debe recuperar correctamente el mensaje original M y llamar al procedimiento output(b) exactamente N veces, con b igual a M[0], M[1],, M[N-1], respectivamente. En la última subtarea, su puntaje varía de acuerdo a la proporción entre las longitudes del mensaje codificado y el mensaje original. Ejemplo Considere el caso donde N = 3, y M= 10 30 20 El procedimiento encode(n,m), usando algún método extraño, puede codificar el mensaje en la secuencia de números (7, 3, 2, 70, 15, 20, 3). Para enviar esta secuencia, debería llamar al procedimiento send como sigue: send(7) send(3) send(2) send(70) send(15) send(20) send(3) Una vez que todos los loros han llegado a su destino, asuma que obtenemos la siguiente lista de números recibidos: (3, 20, 70, 15, 2, 3, 7). El procedimiento decode será llamado entonces con N=3, L=7, y X= 3 20 70 15 2 3 7 El procedimiento decode debe producir el mensaje original (10, 20, 30). Reporta el resultado llamando al procedimiento output como sigue. Página 3 de 6
output(10) output(30) output(20) Subtareas Subtarea 1 (17 puntos) N = 8, y cada entero en el arreglo M es 0 ó 1. Cada entero codificado debe estar en el rango de 0 a R=65535, inclusive. El número de veces que usted puede llamar al procedimiento send es a lo más K=10 N. Subtarea 2 (17 puntos) 1 N 16. Cada entero codificado debe estar en el rango de 0 a R=65535, inclusive. El número de veces que usted puede llamar al procedimiento send es a lo más K=10 N. Subtarea 3 (18 puntos) 1 N 16. Cada entero codificado debe estar en el rango de 0 a R=255, inclusive. El número de veces que usted llama al procedimiento send es a lo más K=10 N. Subtarea 4 (29 puntos) 1 N 32. Cada entero codificado debe estar en el rango de 0 a R=255, inclusive. El número de veces que usted puede llamar al procedimiento send es a lo más K=10 N. Página 4 de 6
Subtarea 5 (hasta 19 puntos) 16 N 64. Cada entero codificado debe estar en el rango de 0 a R=255, inclusive. El número de veces que usted puede llamar al procedimiento send a lo más K=15 N. Importante: el puntaje para esta tarea depende de la proporción entre la longitud del mensaje codificado y la del mensaje original. Para un caso de prueba dado t en esta subtarea, sea Pt=Lt/Nt la proporción entre la longitud Lt del mensaje codificado y Nt la del mensaje original. Sea P el máximo Pt. Su puntaje para esta subtarea será determinado usando las siguientes reglas: Si P 5, usted obtiene todos los 19 puntos. Si 5 < P 6, usted obtiene 18 puntos. Si 6 < P 7, usted obtiene 17 puntos. Si 7 < P 15, su puntaje es 1 + 2 (15 - P), redondeado al entero más cercano. Si P > 15 o cualquiera de sus salidas es incorrecta, su puntaje es 0. Importante: Cualquier solución válida de las subtareas de 2 a 4 también resolverá todas las subtareas que le preceden. Sin embargo, debido al límite grande de K, una solución válida de la subtarea 5 podría no ser capaz de resolver las subtareas de la 1 a la 4. Es possible resolver todas las subtareas usando la misma solución. Detalles de implementación Límites Ambiente de Calificación: En el ambiente real de calificación, sus envíos serán compilados en dos programas e y d a ser ejecutados separadamente. Sus dos módulos encoder y decoder serán vinculados a cada ejecutable, pero únicamente e llama a encode y únicamente d llama a decode. Límite de tiempo: El programa e hará 50 llamadas al procedimiento encode y deberá correr en 2 segundos. El programa d hará 50 llamadas al procedimiento decode y debe correr en 2 segundos. Límite de memoria: 256 MB Nota: No hay un límite explicito del límite de memoria de pila (stack). La memoria de pila cuenta como parte del uso total de memoria.. Página 5 de 6
Interfaz (API) Carpeta de implementación: parrots/ A ser implementado por el participante: encoder.c decoder.c Interfaz del participante: encoder.h decoder.h Interfaz del grader: encoder.h decoder.h Grader para experimentación: grader.c o grader.cpp El grader para experimentación ejecuta dos rondas separadas. En cada ronda, primero llama a encode con los datos dados y luego llama a decode con la salida que produjo su procedimiento encode. En la primera ronda el calificador no cambia el orden de los enteros en el mensaje codificado. En la segunda ronda el grader para experimentación intercambia los enteros en posiciones impares y pares. El grader real aplicará varios tipos de permutaciones a los mensajes codificados. Usted puede cambiar como el grader para experimentación mezcla los datos modificados su procedimiento shuffle (en C/C++). El grader para experimentación también verifica para ambos el rango y la longitud de los datos codificados. Por defecto, verifica que los datos codificados estén en el rango entre 0 y 65535, inclusive, y que la longitud sea a lo más 10xN. Usted puede cambiar esto ajustando las constantes channel_range (de 65535 a a255, por ejemplo) y max_expansion (de 10 a 15, o 7, por ejemplo). Entrada del grader de ejemplo: grader.in.1, grader.in.2,... Nota: El grader de ejemplo lee la entrada con el siguiente formato: Línea 1: N Línea 2: una lista de N números M[0], M[1],, M[N-1] Salida esperada para el grader de experimentación: grader.expect.1, grader.expect.2, Cada uno de estos archivos debe contener precisamente el texto Correct.. Página 6 de 6