La misión
Como es bien sabido, el material genético de todas las criaturas conocidas en la Tierra está codificado en el ADN; utilizando los cuatro nucleótidos adenina, timina, citosina y guanina. (Comúnmente representado por ATGC).
Un bioinformático que desee almacenar un genoma completo, por supuesto, no querría almacenar esto como ASCII, ¡porque cada elección puede representarse con solo dos bits!
La especificación
Su misión, si elige aceptarla, es escribir un par de programas, funciones o métodos para convertir una representación ASCII en una representación binaria y viceversa; representando A
as b00
, T
as b01
, G
as b10
y C
as b11
(en adelante "unidades").
Además, los bits altos de cada byte deben contener el recuento de unidades en el byte, haciendo que cada byte represente un triplete.
Por ejemplo: se "GATTACCA"
convierte b11 100001 b11 010011 b10 1100xx
.
En el ASCII a la entrada binaria, los espacios, las pestañas y las nuevas líneas deben ignorarse. Cualquier carácter que no esté en el conjunto de [ \r\n\tATGC]
es un error y puede ignorarse o finalizar el procesamiento.
En la entrada binaria a ASCII, los bytes cuyos dos bits altos son b00
ignorados.
La salida ASCII puede contener espacios en blanco; pero nunca debe ser más de 4 veces el tamaño de la entrada binaria más un byte de largo, y debe terminar con una nueva línea.
La salida binaria puede contener un número arbitrario de b00xxxxxx
bytes de "control"; pero nunca debe ser más largo que la entrada ASCII.
Cada programa de conversión debe admitir entradas de longitud arbitraria; y debe completar la codificación o decodificación en aproximadamente tiempo lineal.
El giro
Desafortunadamente para el bioinformista para quien está realizando esta tarea, de alguna manera lo ha perjudicado, a nivel personal pero quizás mezquino.
Quizás salió con tu hermana una vez, y nunca la volvió a llamar. Quizás pisó la cola de tu perro. Los detalles no son realmente importantes.
¡Lo importante es que tenga la oportunidad de pagar!
Los detalles
Cada conversión debe introducir una pequeña tasa de error; en el orden de un error por cada diez mil a un millón de unidades procesadas.
Un error puede ser uno de los siguientes:
- Errores de duplicación: se
"GAT TAC CA"
convierte"GAT TAA CCA"
- Errores de eliminación: se
"GAT TAC CA"
convierte en"GAT TAC A"
- Errores de traducción: se
"GAT TAC CA"
convierte"GTA TAC CA"
- Duplicaciones de triplete: se
"GAT TAC CA"
convierte en"GAT TAC TAC CA"
- Deslizamientos de triplete: se
"GAT TAC CA"
convierte en"TAC GAT CA"
- Triplet reversiones: se
"GAT TAC CA"
convierte"GAT CAT CA"
Que los errores se introducirán, por supuesto, no debería ser inmediatamente obvio por el código; e independientemente de la longitud de la entrada; La conversión debe introducir al menos un error.
Dos ejecuciones con entradas idénticas no deberían producir necesariamente salidas idénticas.
El truco
El vil bioinformático es un codificador moderadamente competente; y como tal, algunas construcciones se descubrirán automáticamente y, como tales, se prohibirán:
- Descubrirá automáticamente cualquier llamada a los generadores de números aleatorios del sistema, como rand (), random () o lectura de / dev / urandom o / dev / random (o el equivalente en el idioma).
- También notará las variables superfluas, contadores o bucles.
La puntuación
El codificador y el decodificador se puntuarán individualmente.
Cada uno se ejecutará 3 veces contra un conjunto de 100 archivos de entrada generados aleatoriamente, cada archivo con un tamaño del orden de 3 millones de unidades.
Los datos para los casos de prueba del codificador se crearán aproximadamente de la siguiente manera:
for (l = 1 => bigNum)
for (t = 1 => 20)
random_pick(3,ATGC)
t == 20 ? newline : space
Los datos para los casos de prueba del decodificador se crearán aproximadamente de la siguiente manera:
for (u = 1 => bigNum)
for (t = 1 => 20)
random_byte() | 0b11000000
0x00
El codificador
- Cada byte que falte de la longitud mínima esperada en la longitud real obtendrá -1 puntos, hasta un máximo de -1000. (La longitud mínima esperada es
ceil(count(ATGC) / 3)
).
El decodificador
- Cada byte sobre la longitud máxima esperada en la longitud real obtendrá -1 puntos, hasta un máximo de -1000. (La longitud máxima esperada es
size(input) * 4 + 1
).
Ambos
- Cada tipo de error que pueda producirse obtendrá 100 puntos; para un total de 600 puntos posibles para cada uno, 1200 en total.
- Cada caso de prueba para el cual el codificador produce más del 30% más o menos errores que su propio promedio será penalizado por -5 puntos.
- Cada caso de prueba para el cual el codificador produce menos del 15% más o menos errores que su propio promedio recibirá 5 puntos.
- Cada caso de prueba donde las tres ejecuciones produzcan salidas idénticas será penalizado por -10 puntos.
Requisitos duros
Una entrada será descalificada si:
- Para cualquier entrada válida de más de un triplete, no produce ni siquiera un error.
- Su rendimiento es tal que no puede completar el guante de prueba en aproximadamente una hora.
- En promedio, produce más de un error por cada diez mil unidades.
- En promedio produce menos de un error en cada millón de unidades.
La interfaz
Los participantes deben aceptar la entrada en la entrada estándar y la salida a la salida estándar.
Si la entrada es un programa con doble función; los interruptores -e
y -d
deberían configurar el programa para codificar y decodificar, respectivamente.
Invocaciones de ejemplo:
$ encoder <infile.txt >outfile.bin
$ decoder <infile.bin >outfile.txt
$ recoder -e <infile.txt >outfile.bin
El ganador
El ganador es la entrada con la puntuación más alta; el máximo teórico es 1200 para tipos de error más 3000 puntos para estabilidad en la tasa de generación de errores.
En el caso improbable de un empate; El ganador se determinará por recuento de votos.
Las notas adicionales
Para ejecutar el guante de prueba, cada entrada debe incluir instrucciones de ejecución o compilación.
Todas las entradas deben ejecutarse preferiblemente en una máquina Linux sin X.
fuente
Respuestas:
Perl 5.10
Me alegra presentar mi solución en Perl.
Cuando comencé el desafío, estaba bastante seguro de que Perl se mantendría muy por debajo del límite de 1 hora.
Para fines de prueba, desarrollé un generador de muestra simple y un generador de muestra codificado.
Luego desarrollé el codificador que tomó un mayor esfuerzo y produjo un código más largo. El codificador funciona de la siguiente manera:
La salida binaria codificada tiene el formato de "líneas" terminadas en una nueva línea de 20 octetos, donde cada octeto codifica un triplete, con dos caracteres de prefijo (como un número de línea cíclico).
por ejemplo, la entrada más corta de tres bytes:
debería dar la salida más corta de tres bytes más nueva línea.
es decir
y
debería dar el siguiente binario.
Debería debido a la pequeña tasa de error: para la entrada más pequeña, el script introduce 1 error.
Para una ejecución de archivo de 3 millones de tripletes, el codificador presenta 11 errores.
Siempre que el script sea dnacodec3.pl, la ejecución se invoca en el símbolo del sistema como de costumbre:
El decodificador funciona de la siguiente manera:
Preparé un archivo de prueba de muestra de 3 millones de tripletas (aproximadamente 12 MByte) y probé el tiempo. Al usar mi computadora portátil con un Intel Core i5 vPro a 2.6 GHz, la ejecución del codificador 3M siempre toma menos de 20 segundos. Durante la ejecución toma 200-220 MByte de RAM. ¡Que desperdicio!
La ejecución de decodificación lleva menos de 10 segundos. No puede introducir errores ... por ahora.
De nuevo, para la ejecución de decodificación
Aqui esta el codigo
Y aquí está el generador de muestras:
fuente