El desafío del golf es codificar y comprimir la siguiente imagen dentro de un archivo fuente.
Para ello es necesario escribir 3 funciones: red
, green
y blue
que acepten coordenadas x / y de la imagen y devolver el valor correspondiente R / G / B píxeles entre 0-255.
Aquí está el código de prueba C / C ++:
#include <stdio.h>
#include "your_file"
int main() {
int x, y;
for(y = 0; y < 32; ++y)
for(x = 0; x < 32; ++x)
printf("%i %i %i\n", red(x, y), blue(x, y), green(x, y));
}
Y la salida: http://pastebin.com/A770ckxL (puede usar esto para generar sus datos de imagen)
Reglas y detalles:
- Este es un golf
- Solo su código / archivo es golfed - el código de prueba está separado
- El conjunto de caracteres utilizado es ASCII, sin embargo, los caracteres de control en cadenas solo se pueden usar si se escapan (como '\ n' y '\ r', etc.)
- Todo debe estar contenido dentro de la fuente: sin carga de archivos
- Su salida debe coincidir con la salida de ejemplo. Esto significa compresión sin pérdidas.
Idiomas:
El problema se escribió con C / C ++ en mente, pero estoy eliminando esas restricciones. Dicho esto, todavía recomendaré usarlos.
Respuestas:
C,
796 754 712 703 692 685 682 670 666 662 656648 caracteresRegistro de cambios:
return
a#define
, reemplazandoif
con?
declaraciones (gracias @FUZxxl), eliminandoint
de la lista de parámetros de funciones.#define
p[]
yh[]
, algunas?:
mejoras másb
así quei
ya no es necesario.m=b
en lugar dem=11
y enn<2e3
lugar dei<356
: estos están cerca de un comportamiento indefinido / corrupción de memoria, pero parece que tengo suerte :)k
es ahora (32,16,8,4,2,1,0) en lugar de (5,4,3,2,1,0). Gotcha, DC;)p[]
yh[]
, convertido enh[]
achar*
- awwww, hay un gatito soñoliento^<+_=>-
while
=>for
,l=l*2+...
=>l+=l+...
m=m>9?...
=>c[n++]=m>9?...
b[]
, por lo que podemos asignar a 64-127 en lugar de 0-63 y ya no necesitamos índice de bitsk
. Gracias @Piotr Tarsa . Reemplazado?:
(extensión GCC) con||
. Gracias @JamesBp[]
)La imagen se convierte en una cadena similar a Base64 (ASCII 37-100), utilizando la codificación huffman para codificar los colores 0-9 con 3-6 bits y un color especial 10 (el píxel es el mismo que el anterior) con solo 1 bit.
Copié dos cosas de la respuesta de bunnit, la
#define
y toda la imagen se decodifica completamente cada vez que se llamared
/green
/blue
. Hay espacio para mejoras adicionales, así que espere algunas actualizaciones :) No estoy seguro sobre el cumplimiento del código, usé GCC 4.6.1 para compilar y probar.En cuanto a la compresión, creo que la codificación aritmética ayudaría, ya que la distribución es bastante sesgada, pero tal vez la sobrecarga del código sería demasiado pesada en este caso. LZW también debería hacer un muy buen trabajo. Los colores son bastante locales, por lo que la codificación adaptativa podría ser una idea.
Versión de 754 caracteres más legible con algunos comentarios:
fuente
int
de las listas de parámetros para eliminar algunos bytes más.m=m>9?c[n-1]:m;
paraif(m>9)m=c[n-1];
?if(k<0){j=b[i++]-37;k=5;}
¿ por qué nok>=0?:(j=b[i++]-37,k=5);
? (Este código usa una extensión C de gcc,x=a?:b
es el mismo quex=a?a:b
, con la diferencia de que a se evalúa solo una vez.red(x,y){while(i<356){--k>=0?:(j=b[i++]-37,k=5);l*=2;if(j&(1<<k))l++;for(m=0;m<11;m++)l!=h[m]?:(m=m<=9?:c[n-1],c[n++]=m,l=0,m=12);}return P;}
Python (
684592 caracteres)Dado que este desafío ahora está abierto a todos, ¿por qué no? Es la ruta de codificación familiar zlib -> base64, así que me disculpo por eso. ¡Esperemos que una entrada con cierta apariencia de ingenio sea más corta!
Aquí hay un fragmento de prueba análogo al original:
fuente
C ++, 631 caracteres; C - 613
Un codificador mtf unario base-92, C ++, 631 caracteres:
Y la versión C de arriba (613 caracteres):
Solo para incluir una entrada con datos de base 95 y codificación aritmética + modelo estadístico adaptativo.
El código de Schnaader utiliza ~ 438 caracteres para datos, y el mío solo 318 (311 sin enmascaramiento).
Pero como se esperaba, la codificación aritmética es demasiado complicada para una muestra pequeña como esta.
(Esto es 844 caracteres)
Pruebas (de la versión anterior de base-96):
http://codepad.org/qrwuV3Oy
http://ideone.com/ATngC
De alguna manera SO come códigos 7F, así que tuve que actualizarlo a base = 95
fuente
C ++ -
15251004964 caracteresCreó una matriz z que almacena todos los colores posibles como un solo entero. (R << 16 | g << 8 | b). Creado una matriz d que almacena {cantidad, valor}, el valor es la posición en la matriz z, la cantidad es el número de píxeles consecutivos con ese valor (es decir, 3,0, significa que el color t [0] aparece los siguientes 3 píxeles. La matriz real de píxeles (c) se calcula cada vez que se llama rojo. El valor en la matriz se desplaza a la derecha y se AND según sea necesario para obtener el componente correcto.
Probablemente podría guardar algunos caracteres más (~ 50) tomando más patrones de la matriz como se define.Editar 1 : cambió la matriz d para una matriz de caracteres con cada valor compensado por 48, lo que significa que puedo representarlo como una cadena que ahorra una gran cantidad de comas.
Edición 2 : tomó una porción más grande de las funciones en la declaración de definición.
fuente
int
así (seint f(int x,int y)
convierte asíf(x,y)
.Javascript,
696694caracteresGracias a schnaader por 696 -> 694.
Imaginé un formato de codificación diferente, que esencialmente es la codificación Run-length con una tabla de búsqueda de color. Funciona bastante bien, porque hay menos de 16 colores y aparecen menos de 16 veces seguidas; así que cada definición de píxel, incluida la longitud, cabe en un byte. Puse el color en la parte alta del byte y la cuenta en la parte baja.
Al final, la cadena base64 resultó ser más larga de lo que esperaba (472 caracteres), pero el programa de decodificación es realmente corto.
Nota: dividí el código para tener un poco de legibilidad. Tiene que estar en una línea para ejecutarse.
Código de prueba:
Creo que el resultado del ejemplo es en realidad la salida de rojo, verde, azul (no rojo, azul, verde como en el código de prueba original); Funciona para mí así de todos modos.
fuente
[0,16354410,4671418,6379596,7783255,5295994,5390379,3435360,9975021,5131894]
: esto ahorra 1 carácter y es el orden GBR en lugar de RGB.C ++, 1357 caracteres
Desobuscado un poco:
C
contiene los valores RGB para los diez colores distintos de la imagen.E
contiene los datos para la imagen, donde cada elementoE[i]
codifica un recuento repetidoE[i]/10
y un índice de colorE[i]%10
.fuente
int red(x,y){R Q(x+32*y)[0]}(only
# define`return
), es posible que pueda eliminar más caracteres.Python 3 (589 caracteres)
Código de prueba
Basado en la solución de Dillon Cower
fuente
PHP (5.4) - 822
He hecho esto deliberadamente sin usar ninguna de las funciones de compresión integradas . Esta solución no está terminada, no estoy seguro si me he rendido, puedo ver áreas para mejorar, pero no puedo encontrar el tiempo / fuerza de voluntad para refactorizar todo en este momento, así que estoy publicando lo que tener hasta ahora.
Nuevas líneas + comentarios que se eliminarán para 822 bytes.
Trozo de prueba:
La compresión de los datos de la imagen en sí es bastante buena, pero las funciones para recuperar valores RGB ocupan 1/4 del código.
Estoy usando un mecanismo de codificación de longitud de ejecución base70 + personalizado.
Los datos de la imagen codificada hacen referencia al índice de matriz de un RLE, que a su vez indexa la matriz de colores. No estoy seguro de la cantidad de gastos generales que esto agrega o resta sobre hacer referencia directa a los colores.
Sinusoidal hay 10 colores (0 a 9), los RLE se almacenan como
run_length * 10 + colour_index
. Dando un rango de codificaciones entre 10 y 145 sin experimentar con optimizaciones basadas en el orden de color. (es decir, podría hacer el rango de 19 a 140 moviendo los colores de 0 a 5, de 5 a 9 y de 9 a 0, pero esto puede tener otros efectos colaterales)Una respuesta anterior indica que sus datos codificados son 472 bytes. Los datos de mi imagen codificada son 352 bytes, pero el mapa de color / RLE intermedio (que no está codificado en binario) es otros 129 bytes, lo que pone el total en 481. (así como una sobrecarga adicional para unir los dos). Sin embargo, sospecho que mi método podría escalar mejor para imágenes más grandes.
QUE HACER:
global
es una perra, pero no puede acceder a los índices de caracteres en las constantes.fuente
C (gcc) , 602 bytes
Pruébalo en línea!
En mal estado
fuente