Comprimir para impresionar


8

Inspirado tanto en el desafío "Unique is Cheap" de @Laikoni , donde la puntuación se basa en el desafío en sí mismo, como en la respuesta de JavaScript (ES6) de @ETHproductions para el desafío "Compresión de palíndromo " , donde utiliza una muy buena método de compresión para la bandera de palíndromo, indicación de mayúsculas / minúsculas y letras.

Desafío:

Creará dos programas / funciones: un programa / función de compresión y un programa / función de descompresión.

Comprimir programa / función:

Dados los caracteres utilizados en su propio código fuente (el código fuente comprimido y descomprimido combinado) como única entrada posible, utilice cualquier tipo de método de compresión de bits de su elección y genere los 0s y 1s resultantes de la compresión de bits de esta entrada .

La cantidad de bits ( 0s y 1s) emitidos debe ser lo más corto posible, y esta cantidad será la puntuación de su respuesta .

La idea es tener un buen equilibrio entre los diferentes tipos de caracteres utilizados en su propio código fuente, el tamaño de sus programas / funciones y el tipo de compresión de bits que ha utilizado. O para citar a @RobertFraser en este comentario :

Este es un gran ejemplo de los fundamentos de la ingeniería. Tomar una descripción del problema, pensar en diferentes formas de resolverlo y hacer compensaciones entre los requisitos (es decir, cuántos bits dedicar a varios estilos), etc.

Reglas de desafío:

  • El programa / función del compresor y descompresor debe estar en el mismo lenguaje de programación.
  • Debe proporcionar tanto una compresión y descompresión de programa / función, y la cantidad de 0s y 1s sus productos de los programas de compresión para ambos programas / funciones combinadas (concatted) como entrada será su puntuación.
  • La compresión debe, obviamente, funcionar para todos los caracteres utilizados en su código fuente de su programa / función de compresión y descompresión, en cualquier orden o cantidad. (Puede tener un comportamiento indefinido para cualquier carácter que no esté en su código fuente).
  • El tipo de entrada no necesariamente tiene que ser una cadena. También podría ser una lista / matriz / secuencia de caracteres, y puede ser como argumento de programa, STDIN, etc. Su llamada.
    Lo mismo se aplica a la salida. Puede devolverse desde una función o imprimirse en STDOUT. Puede ser una sola cadena, una matriz de enteros, etc.
  • Su programa de compresión debe generar al menos uno 0o 1(por catlo que no es posible un programa vacío para el programa de compresión y descompresión).
  • Es posible que su código fuente no solo contenga 0sys 1, ya que excluye no-ops (para evitar lenguajes de programación que impriman su propio código fuente de forma predeterminada, donde los programas de compresión y descompresión pueden ser un solo 0o 1, y la parte no-ops es para evitar este comportamiento con un comentario no utilizado; lo siento, lenguajes de programación basados ​​en binarios que solo usan 0sy 1s como código fuente).
  • Aunque tendrá que admitir una entrada de 0 o más del conjunto de caracteres utilizado en sus programas / funciones, no tiene que admitir una entrada vacía. Por lo tanto, puede asumir que cada entrada tendrá al menos 1 carácter.
  • Una posible entrada puede ser mayor que los tamaños de compresión y descompresión combinados.
  • Si, por alguna razón, su método de compresión depende del orden y tiene una salida más corta cuando su entrada es en DecompressionProgramCompressionProgramlugar de CompressionProgramDecompressionProgram, puede elegir cualquier orden de concatenación de sus programas / funciones para su puntaje.

Ejemplo:

Digamos que el programa de compresión es ABCy el programa de descompresión es 123aBc. Para cualquier entrada que contenga cero o más de la agrupación de caracteres 123ABCab, debería poder comprimir correctamente esos caracteres a 0sy 1s, y poder descomprimir estos 0sy 1s nuevamente en los caracteres correctos. Algunas entradas de ejemplo válidas para estos dos programas pueden ser: ABC123aBc(por supuesto); A; 1Ca; 22222b1121221b; etc.

Reglas generales:

  • Se aplican reglas estándar para su respuesta, por lo que puede usar STDIN / STDOUT, funciones / método con los parámetros adecuados, programas completos. Tu llamada.
  • Las lagunas predeterminadas están prohibidas.
  • Si es posible, agregue un enlace con una prueba para su código.
  • Además, agregue una explicación si es necesario.

Ejemplo de una respuesta:

Java 8, puntaje 1440 bits, 180 (87 + 93) bytes

Aquí una implementación muy mala en Java 8, donde cada carácter simplemente se imprime como una cadena binaria de 8 bits.

Función de compresión:

Entrada proporcionada como java.util.stream.IntStream.

s->s.forEach(c->System.out.print("".format("%8s",Long.toString(c,2)).replace(' ','0')))

Pruébalo en línea.

Función de descompresión:

Entrada proporcionada como String.

s->{for(Integer i=0;i<s.length();System.out.printf("%c",i.parseInt(s.substring(i,i+=8),2)));}

Pruébalo en línea.


Esta no es una prueba de quine, ¿puedo leer mi código fuente?
Weijun Zhou

@WeijunZhou Depende de para qué lo use, pero probablemente lo permita en la mayoría de los casos. Supongo que quieres leer tu código fuente y luego mapear fácilmente sus caracteres con una tabla de búsqueda, o algo así.
Kevin Cruijssen

Sí, algo similar está en mi mente.
Weijun Zhou

1
Puede que me haya perdido algo, pero aquí hay una posible laguna en las reglas: compresor-> if input==compr_code+decompr_code then return 0 else return binary charcodes of input, descompresor-> if input==0 then return compr_code+decompr_code else convert binary codes to characters and return them. Puntuación final: 1 (la más baja posible). Los programas no serán triviales para escribir, pero con algunos trucos de quines seguramente son factibles.
Leo

@Leo Hmm, tienes razón en que las reglas actuales permiten esa respuesta (sin querer, por supuesto). Sin embargo, no estoy seguro de cómo solucionarlo. Podría decir que debe proporcionar el mapeo que ha utilizado para cada carácter individual, que debe corresponder / ser el mismo para la entrada de compresor + descompresor, así como cualquier configuración aleatoria de estos caracteres. Pero en ese caso, podría limitar las posibles respuestas que desean comprimir pares de caracteres, o lo que sea que se les ocurra. ¿Alguna sugerencia sobre una regla para cerrar este agujero de bucle, pero aún así dejar cierta flexibilidad para la creatividad? ..
Kevin Cruijssen

Respuestas:



2

Java (OpenJDK 9) , puntaje 702 bits, 88 (42 + 46) bytes

Compresor, 42 bytes.

$->new java.math.BigInteger($).toString(2)

Pruébalo en línea!

Descompresor, 46 bytes

$->new java.math.BigInteger($,2).toByteArray()

Pruébalo en línea!


Lo siento, estoy jugando el bajo costo de bytes ( hum , para Java, quiero decir) en lugar de la compresión dura: S
Olivier Grégoire

Ni siquiera sabía que era posible poner alguno Stringen el BigIntegerconstructor. Pensé que daría una excepción NumberFormatException o algo así. Sabía sobre el .toString(2). Buen golf de mi respuesta de ejemplo, supongo. ;)
Kevin Cruijssen

@KevinCruijssen De hecho, como es actualmente, es más un ejemplo de golf que otra cosa. 703 bits significa 88 bytes. No pude comprimir nada en menos de 88 bytes hasta ahora, pero todavía estoy tratando de hacerlo ;-)
Olivier Grégoire

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.