Tu misión hoy es inventar un compresor de texto.
Tarea
Escribirás dos funciones:
El empaquetador es una función que acepta una cadena de caracteres ASCII (U + 0000 a U + 007F) y genera una cadena Unicode (U + 0000 a U + 10FFFF), que contiene la menor cantidad de caracteres posible.
El desempacador es una función que acepta una cadena Unicode codificada y genera exactamente la cadena ASCII original.
Entrada
La única entrada autorizada es la cadena ASCII (para el empacador) y la cadena Unicode empaquetada (para el desempacador). Sin entrada del usuario, sin conexión a Internet, sin uso del sistema de archivos.
Sus funciones pueden tener acceso a esta lista de palabras en inglés . Puede usar esta lista como un archivo txt local, o copiar su contenido en su código fuente como una cadena o una matriz de cadenas .
No puede codificar los fragmentos a continuación en sus funciones.
Salida
La única salida autorizada para ambas funciones es una cadena.
La salida del desempacador debe contener exactamente los mismos caracteres que la entrada del empacador.
Sus entradas y salidas pueden usar cualquier codificación de caracteres que admita todos los Unicode (UTF-8/16/32, GB18030, ...), ya que su puntaje solo dependerá de la cantidad de caracteres Unicode en la salida. Sin embargo, precisa qué codificación estás usando.
Para contar el número de caracteres Unicode en su salida, puede usar esta herramienta: http://mothereff.in/byte-counter
Tanteo
Su entrada debe poder empaquetar y desempaquetar los siguientes 10 fragmentos de texto (que tomé en este foro).
Su puntaje será la suma de los tamaños de sus 10 cadenas empaquetadas (en caracteres Unicode) + el tamaño de sus dos funciones (también en caracteres Unicode)
No cuente el tamaño del diccionario si lo usa.
Incluya en sus entradas el "puntaje" de cada fragmento y su versión empaquetada.
La puntuación más baja gana.
Datos
Estos son los fragmentos para codificar para calcular su puntaje:
1: Letras de Rick Roll (1870b): No somos ajenos al código de golf, conoces las reglas, y yo también
No somos extraños para amar Conoces las reglas y yo también Un compromiso total es lo que estoy pensando No obtendrías esto de ningún otro chico Solo quiero decirte cómo me siento Tengo que hacerte entender Nunca va a dar Nunca te voy a decepcionar Nunca voy a correr y abandonarte Nunca te haré llorar Nunca voy a decir adios Nunca diré una mentira y te lastimaré Nos conocemos desde hace tanto tiempo Tu corazón ha estado doliendo pero Eres demasiado tímido para decirlo En el interior, ambos sabemos lo que ha estado sucediendo. Conocemos el juego y lo vamos a jugar. Y si me preguntas cómo me siento No me digas que estás demasiado ciego para ver Nunca va a dar Nunca te voy a decepcionar Nunca voy a correr y abandonarte Nunca te haré llorar Nunca voy a decir adios Nunca diré una mentira y te lastimaré Nunca va a dar Nunca te voy a decepcionar Nunca voy a correr y abandonarte Nunca te haré llorar Nunca voy a decir adios Nunca diré una mentira y te lastimaré (Ooh, te rindo) (Ooh, te rindo) (Oh) Nunca daré, nunca daré (Te rindo) (Oh) Nunca daré, nunca daré (Te rindo) Nos conocemos desde hace tanto tiempo Tu corazón ha estado doliendo pero Eres demasiado tímido para decirlo En el interior, ambos sabemos lo que ha estado sucediendo. Conocemos el juego y lo vamos a jugar. Solo quiero decirte cómo me siento Tengo que hacerte entender Nunca va a dar Nunca te voy a decepcionar Nunca voy a correr y abandonarte Nunca te haré llorar Nunca voy a decir adios Nunca diré una mentira y te lastimaré Nunca va a dar Nunca te voy a decepcionar Nunca voy a correr y abandonarte Nunca te haré llorar Nunca voy a decir adios Nunca diré una mentira y te lastimaré Nunca va a dar Nunca te voy a decepcionar Nunca voy a correr y abandonarte Nunca te haré llorar Nunca voy a decir adios Nunca diré una mentira y te lastimaré
2: El golfista (412b): Golf ASCII-art
'\. . |> 18 >> \. '. El | O >>. 'o | \. El | / \. El | / /. ' El | jgs ^^^^^^^ `^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^
3: el diamante número (233b): imprime este diamante
1 121 12321 1234321 123454321 12345654321 1234567654321 123456787654321 12345678987654321 123456787654321 1234567654321 12345654321 123454321 1234321 12321 121 1
4: el alfabeto cuatro veces (107b): imprime el alfabeto cuatro veces
ABCDEFGHIJKLMNOPQRSTU VWXYZ qwertyuiopasdfghjklzxcvbnm pyfgcrlaoeuidhtnsqjkxbmwvz zyxwvutsrqponmlkjihgfedcba
5: Letras de Old McDonald's (203b): Función de Old MacDonald
El viejo MacDonald tenía una granja, EIEIO, Y en esa granja tenía una vaca, EIEIO, Con un mu mu mu aquí y un mu mu mu allá Aquí un mu, hay un mu, en todas partes un mu, ¡El viejo MacDonald tenía una granja, EIEIO!
6: Letra de Rock around the clock (144b): Rock Around the Clock
1, 2, 3 en punto, 4 en punto de roca, 5, 6, 7 en punto, 8 en punto de roca, 9, 10, 11 en punto, roca a las 12 en punto, Vamos a rockear todo el día esta noche.
7: Hola Mundo (296b): Di "Hola" al mundo en el arte ASCII
_ _ _ _ _ _ _ El | El | El | El | ___ | El | El | ___ __ _____ _ __ | El | __ | El | El | El | | _ | | / _ \ | | / _ \ \ \ / \ / / _ \ | | '__ | | / _` | El | El | _ | __ / | El | (_) | \ VV / (_) | El | El | El | (_ | | _ | | _ | | _ | \ ___ | _ | _ | \ ___ () \ _ / \ _ / \ ___ / | _ | | _ | \ __, _ (_) | /
8: bendición irlandesa (210b): una antigua bendición irlandesa
Que el camino se levante para conocerte Puede que el viento esté siempre a tu espalda Que el sol brille sobre tu rostro Las lluvias caen suaves sobre tus campos Y hasta que nos encontremos de nuevo Que Dios te sostenga en el hueco de su mano
9: Había una vieja dama (1208b): Había una vieja dama
Había una anciana que tragó una mosca. No sé por qué se tragó esa mosca Quizás ella muera. Había una anciana que se tragó una araña, Eso se retorció, se sacudió y se sacudió dentro de ella. Ella se tragó la araña para capturar la mosca, No sé por qué se tragó esa mosca Quizás ella muera. Había una anciana que se tragó un pájaro, Qué absurdo tragarse un pájaro. Se tragó el pájaro para atrapar a la araña, Ella se tragó la araña para capturar la mosca, No sé por qué se tragó esa mosca Quizás ella muera. Había una anciana que se tragó un gato, Imagina que tragar un gato. Se tragó al gato para atrapar al pájaro, Se tragó el pájaro para atrapar a la araña, Ella se tragó la araña para capturar la mosca, No sé por qué se tragó esa mosca Quizás ella muera. Había una anciana que se tragó un perro, Qué cerdo tragarse un perro. Se tragó al perro para atrapar al gato, Se tragó al gato para atrapar al pájaro, Se tragó el pájaro para atrapar a la araña, Ella se tragó la araña para capturar la mosca, No sé por qué se tragó esa mosca Quizás ella muera. Había una anciana que se tragó un caballo, Ella murió por supuesto.
10: dirección de Gettysburg (1452b): cuán aleatoria es la dirección de Gettysburg
Hace cuatro años y siete años, nuestros padres dieron a luz en este continente una nueva nación, concebida en libertad, y dedicada a la proposición de que todos los hombres son creados iguales. Ahora estamos involucrados en una gran guerra civil, probando si esa nación, o cualquier nación tan concebida y dedicada, puede perdurar por mucho tiempo. Nos encontramos en un gran campo de batalla de esa guerra. Hemos llegado a dedicar una parte de ese campo, como un lugar de descanso final para aquellos que aquí dieron sus vidas para que esa nación pudiera vivir. Es totalmente apropiado y apropiado que hagamos esto. Pero, en un sentido más amplio, no podemos dedicar, no podemos consagrar, no podemos santificar este terreno. Los hombres valientes, vivos y muertos, que lucharon aquí, lo han consagrado, muy por encima de nuestro pobre poder para sumar o restar valor. El mundo notará poco, ni mucho tiempo recordará lo que decimos aquí, pero nunca puede olvidar lo que hicieron aquí. Es para nosotros los vivos, más bien, dedicarnos aquí al trabajo inacabado que los que lucharon aquí han avanzado hasta ahora noblemente. Es más bien para nosotros estar aquí dedicados a la gran tarea que nos queda por delante: que de estos honrados muertos tomemos una mayor devoción a esa causa por la cual dieron la última medida completa de devoción, que aquí resolvamos altamente que estos muertos no han muerto en vano, que esta nación, bajo Dios, tendrá un nuevo nacimiento de libertad, y que el gobierno del pueblo, por el pueblo, por el pueblo, no perecerá de la tierra.
Total (sin comprimir): 6135 caracteres / bytes.
¡Que te diviertas!
private static final String RICK_ROLL_RETURN = "We're no strangers to love...
Respuestas:
Haskell - 5322 puntos
Bytes de código:
686
Tamaño original :
6147
= 1871+415+234+108+204+145+297+211+1209+1453
Tamaño codificado:
4636
= 1396+233+163+92+153+115+197+164+979+1144
Puntuación :
686+ 4636
Compresión de recuento de caracteres:
~25%
Código
Dejando de lado las optimizaciones, esto almacena valores entre
0
y7f
en caracteres unicode como sus factores primos.No reduce el número de bytes de la salida codificada, solo reduce el número de caracteres unicode. Por ejemplo, la prueba # 4 contiene
108
personajes y la salida codificada,92
. Sus respectivos tamaños son, sin embargo108
, y364
bytes.Cómo funciona
Codificación
n
.n
luego se convierte en una lista de sus factores primos,ps
.1
. Esto significa que ellos, los factores, pueden almacenarse como índices en tan solo 5 bits.1
es un caso especial y está representado por una lista vacía.ps
la codificación ahora puede comenzar.ps
se convierte en su índice en la lista de 32 factores únicos (en el código anterior, esta lista se identifica comoa
).ps
debe aplanarse. Para preservar la integridad de los datos, cada lista se convierte en otra lista de dos partesfs
.fs
se pueden empaquetar en caracteres unicode utilizando desplazamiento de bits.Descodificación
1
encaja en esto, me gustaría recordarle esoproduct [] == 1
.Pruebas
Usar esta interfaz para probar sería doloroso, así que usé esta función para proporcionar los resultados a continuación.
Muestra
La salida de la función de codificación
g
para la prueba n. ° 4 es esta"\99429\582753\135266\70785\35953\855074\247652\1082563\68738\49724\164898\68157\99429\67973\1082404\587873\73795\298017\330818\198705\69861\1082435\595009\607426\36414\69873\855074\265249\346275\67779\68738\77985\1082513\821353\132131\101410\247652\1082562\49724\164898\67649\594977\34915\67746\50273\135265\103997\563265\103457\1086021\99399\584802\70753\73889\34882\582722\411459\67779\68740\1084516\1082563\1091681\103491\313282\49724\164897\68705\135741\69858\50241\607426\35905\608421\1082435\69858\50274\71777\43075\298018\280517\1082404\67971\36017\955425\67665\919600\100452\132129\214883\35057\856097\101474\70753\135737"
o, si eres un experto en galimatías, esto
𘑥𡁢𑒁豱𐲂숼𨐢𘑥𐦅𒁃𰠱𑃥踾𑃱𐲂𓂡𠐣𘰢숼𨐢𐡁衣쑡𡁡𘑇𑑡𒂡衂𐲄숼𨐡𡈽𑃢쑁豁𑃢쑢ꡃ𐦃貱𐡑𘡤𠐡裱𘱢𑑡𡈹
Notas adicionales
edTest
el tamaño de las pruebas son todos consistentes pero aún difieren del tamaño indicado en la pregunta.—
) que reemplacé con-
ya que están fuera de la0
-7f
gama.00
caso base,01
repetir todo,10
repetir excepto el último,11
repetir excepto los últimos dos.fuente
abcdefghijklm...
a𘑥𡁢𑒁豱...
, ¿podría explicar un poco más, por favor? Además, arreglé los recuentos de caracteres y convertí los guiones en # 10, en la pregunta. Sin embargo, mis recuentos de caracteres siguen siendo diferentes a los tuyos. No sé por qué, utilicé la herramienta mothereff.in.C ++ (C ++ 11), 2741 puntos
Esta respuesta usa UTF-32 como codificación para el texto comprimido.
Char cuenta y anota
Código: 593 caracteres (la nueva línea final se elimina)
Textos comprimidos (caracteres unicode) : 654 + 145 + 82 + 38 + 51 + 104 + 73 + 423 + 506 = 2148 (contados con
wc -m
el número de caracteres unicode en lugar de bytes, los recuentos de bytes son, como con la respuesta de @ gxtaillon , superior a los originales, 8413 bytes en total, según se cuenta conwc -c
).Relación de compresión (ASCII a Unicode) : 35.01% (utilizando los 6135 bytes de la pregunta (igual que
wc -c
))Tener cuidado:
Muchos shells no pueden manejar los caracteres unicode que produce este programa. Por lo tanto, la descompresión puede hacer que el texto se corte en algún lugar cuando el shell no puede manejar un carácter, ya que la entrada se toma a través de
stdin
desde el shell.Compilando
Debería compilar con
clang++
yg++ -std=c++11
, pero mostrará algunas advertencias sobre la precedencia del operador, ya que una expresión comob<<20-n&0xFFFFF
no se tratará como((b << 20) - n) & 0xFFFFF
, como cabría esperar, sino como(b << (20 - n)) & 0xFFFFF
.Uso
./compress
../compress c
para comprimir o./compress d
descomprimir. (Cuidado, dejar de lado la opción da un SEGFAULT (la comprobación de errores es muy costosa ...) y otras opciones (como usarD
lugar ded
) pueden dar resultados inesperadosstdin
y la salida se escribe enstdout
Cómo funciona
Sin golf
Explicación
Como todos los caracteres Unicode de
U+0000
aU+10FFFF
están permitidos, podemos usar 20 bits por char Unicode:U+FFFFF
usa 20 bits y todavía está incluido en el rango permitido. Por lo tanto, solo intentamos meter todos los bits de caracteres ASCII individuales en los caracteres unicode para almacenar múltiples caracteres ASCII en un carácter unicode. Sin embargo, también necesitamos almacenar el número de bits utilizados en el último carácter unicode, porque los bits basura no utilizados pueden interpretarse como caracteres ASCII comprimidos adecuados. Como el número máximo de bits usados en el último carácter unicode es 20, necesitaremos 5 bits para eso, que se colocan al comienzo de los datos comprimidos.Salida de ejemplo
Este es el resultado, por ejemplo, # 4 (según lo dado por
less
):(
쏏𦛏
dar<U+C3CF><U+266CF>
como códigos de caracteres, pero podría haberme equivocado)fuente
Python 3, 289 + 818 = 1107 puntos
Solo ligeramente golfizado.
El tamaño total del código es de 289 bytes y codifica los 6135 bytes dados en 818 caracteres Unicode: el recuento total de bytes de salida es 3201 bytes, significativamente más pequeño que las entradas originales.
Codifica usando zlib, luego secundariamente usando codificación unicode. Se necesitaba algo más de lógica para evitar sustitutos (que Python realmente odia).
Ejemplo de salida del # 4, como se ve en
less
(37 caracteres Unicode):Programa de controlador para pruebas:
El byte de salida cuenta:
fuente
p
es el empacador,u
es el desempacador.Python 2 - 1141 puntos
El tamaño del código es
281
bytes y codifica los6135
bytes en860
caracteres unicode.Cómo funciona:
Para codificar:
19
bits, agregue un1
bit al comienzo de cada uno de ellos y luego conviértalos en caracteres Unicode.La decodificación es lo contrario.
Tenga en cuenta que algunas versiones de python solo pueden manejar caracteres unicode hasta y
0xFFFF
, por lo tanto, este código generará unValueError
.fuente