Codificar una imagen dentro de la fuente

10

El desafío del golf es codificar y comprimir la siguiente imagen dentro de un archivo fuente.

Imagen

Para ello es necesario escribir 3 funciones: red, greeny blueque 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.

Pubby
fuente
44
Si no hay una razón específica para hacerlo, se desaconseja corregir una pregunta a un idioma específico. ¿Cuál es la razón por la cual uno no debe usar otros idiomas?
FUZxxl
3
Si una solución es menos interesante, no la vote. Prohibir las soluciones "poco convincentes" excluyendo idiomas es excesivo.
FUZxxl
2
Si ya ha limitado el conjunto de caracteres a ASCII (lo cual considero absolutamente correcto), ¿cómo podríamos usar hacks Unicode? En cuanto a la base 64, puede hacerlo dentro del estándar C, así como en cualquier otro lenguaje, solo con diferentes cantidades de código contenedor. - Pero me gusta la tarea.
dejó de girar en contra del reloj el
1
Hmm, ¿qué pasa con los caracteres de control ASCII 0-31 (y 127)? Técnicamente, son parte de ASCII, pero ¿están permitidos? Y si no, espero que al menos se haga una excepción para el carácter LF (10), y tal vez CR (13) y TAB (9) también.
Ilmari Karonen
1
Um ... entonces, leyendo su nueva versión literalmente, todas las soluciones tienen que estar en una línea, porque no se permiten avances de línea sin escape. ¿Es eso realmente lo que pretendes?
Ilmari Karonen

Respuestas:

6

C, 796 754 712 703 692 685 682 670 666 662 656 648 caracteres

Registro de cambios:

  • 754-> 712: agregado returna #define, reemplazando ifcon ?declaraciones (gracias @FUZxxl), eliminando intde la lista de parámetros de funciones.
  • 712-> 703: copia desvergonzada de bunnit de nuevo :) Se trasladó toda la creación de la imagen al #define
  • 703-> 692: fusionado p[]y h[], algunas ?:mejoras más
  • 692-> 685: Incrementar basí que iya no es necesario. m=ben lugar de m=11y en n<2e3lugar de i<356: estos están cerca de un comportamiento indefinido / corrupción de memoria, pero parece que tengo suerte :)
  • 685-> 682: kes ahora (32,16,8,4,2,1,0) en lugar de (5,4,3,2,1,0). Gotcha, DC;)
  • 682-> 670: dividir p[]y h[], convertido en h[]a char*- awwww, hay un gatito soñoliento^<+_=>-
  • 670-> 666: while=> for, l=l*2+...=>l+=l+...
  • 666-> 662: m=m>9?...=>c[n++]=m>9?...
  • 662-> 656: orden de bits invertido b[], por lo que podemos asignar a 64-127 en lugar de 0-63 y ya no necesitamos índice de bits k. Gracias @Piotr Tarsa . Reemplazado ?:(extensión GCC) con ||. Gracias @JamesB
  • 656-> 648: copia desvergonzada de Shelwien :) (constantes de varios caracteres para p[])

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.

#define P (x,y){for(;n<2e3;j/=2){j>1||(j=*b+++27);l+=l+(j&1);for(m=0;m<11;m++)l-h[m]+32||(c[n++]=m>9?c[n-1]:m,l=0,m=b);}return 255&p[c[x+y*32]]
char*h="$^<+_=>-,* ",*b="F0(%A=A=%SE&?AEVF1E01IN8X&WA=%S+E+A-(,+IZZM&=%]U5;SK;cM84%WE*cAZ7dJT3R.H1I2@;a^/2DIK&=&>^X/2U*0%'0E+;VC<-0c>&YU'%],;]70R=.[1U4EZ:Y=6[0WU4%SQARE0=-XDcXd_WW*UAF&cFZJJ0EV*(a(P05S3IXA>51cH:S5SAE6+W%/[]7SF(153UM]4U()(53DA+J:]&5+5KX,L6>*4I,/UMBcML9WKLa9%UYIHKWW(9-*):(-ZW(9%T'N&9;C,C/Ea/Y7(JJ\\6CD9E,2%J*,ac]NIW8(M=VFac)/^)?IS-;W&45^%*N7>V,,C-4N35FMQaF,EaWX&*EJ4'";p[]={0,'R@+','aXL',7783255,'4k`',16354410,'NNv',5295994,4671418,9975021},c[1024],j,l,m,n;red P;}blue P>>16;}green P>>8;}

Copié dos cosas de la respuesta de bunnit, la #definey toda la imagen se decodifica completamente cada vez que se llama red/ 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:

#define P 255&p[c[x+y*32]]
// Base64 coded image bitstream, ASCII 37-100
// Huffman codes: 100, 111110, 11100, 1011, 111111, 11101, 11110, 1101, 1100, 1010, 0
char b[]="FYU%3+3+%B&E;3&HF1&Y1.JWXE83+%B=&=3)U]=.PP*E+%,('?B>?D*Wa%8&MD3P7dNbARIV1.Q[?4L9Qc.>E+EKLX9Q(MY%5Y&=?HC_)YDKE0(5%,]?,7YR+I@1(a&PO0+G@Y8(a%B23R&Y+)XcDXd<88M(3FEDFPNNY&HMU4UZY'BA.X3K'1DVOB'B3&G=8%9@,7BFU1'A(*,a(U-U'Ac3=NO,E'='>X]^GKMa.]9(*SD*^/8>^4/%(0.V>88U/)M-OU)P8U/%b5JE/?C]C9&4907UNN`GCc/&]Q%NM]4D,J.8WU*+HF4D-9L-;.B)?8Ea'L%MJ7KH]]C)aJA'F*24F]&48XEM&Na5";
// Colors, order GBR (one char shorter than all the others)
p[]={0,5390379,6379596,7783255,3435360,16354410,5131894,5295994,4671418,9975021};
// Huffman codes for colors 0-10
h[]={4,62,28,11,63,29,30,13,12,10,0};
// Array for image data
c[1024];
i,j,k,l,m,n;
red(int x,int y){
  while(i<356){
    k--;
    if (k<0) {
      j=b[i++]-37;
      k=5;
    }
    l*=2;
    if (j&(1<<k)) l++;
    for(m=0;m<11;m++){
      if(l==h[m]){
        if (m>9) m=c[n-1];
        c[n++]=m;
        l=0;
        m=12;
      }
    }
  }
  return P;
}
blue(int x,int y){return P>>16;}
green(int x,int y){return P>>8;}
Schnaader
fuente
Muy bien, no puedo creer que no haya pensado en usar la base 64. Creo que todavía puedes guardar bastantes caracteres, especialmente en ese ciclo. Funciona bien en VS2008 por cierto.
Scott Logan
Creo que puede eliminar eso intde las listas de parámetros para eliminar algunos bytes más.
FUZxxl
¿Qué tal m=m>9?c[n-1]:m;para if(m>9)m=c[n-1];?
FUZxxl
Y también: if(k<0){j=b[i++]-37;k=5;}¿ por qué no k>=0?:(j=b[i++]-37,k=5);? (Este código usa una extensión C de gcc, x=a?:bes el mismo que x=a?a:b, con la diferencia de que a se evalúa solo una vez.
FUZxxl
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;}
FUZxxl
4

Python ( 684 592 caracteres)

red,blue,green=[lambda x,y,i=i:[15570996,2839104,7010700,5732035,6304875,0,12207943,8016079,7753294,5005656][int('eJxtkgGSxSAIQ6+kaLTe/2JLImj7Z9MZ6/gMIgjAzMbVWisGySRNm2ut5Hhx/2M0JMfHH5PWwo9x4mNO8pb6JkFM3hpqrR4+qY6eVK1mjlsFeSOBjPyCMy3348aXVRtq9X8czovMIwA5FeXKtGOcvfcf/lbvyW0n2BTOh122HiIH0g/uNrx47zupzMxuuTv808pZd3K7deJ/+PiH61AztmaNwPAsOnNGYovWIxswRill6vnAL4HgxDF17jFcjwRk/5b3Q1x1flLI9n64CIci8bmQe7NL8XoKliu+Jk/AR9rnjkwAYaDka8OXu/a+5NvvNzkcmqifL47H04kAz9M+9slKkDMGuOHi5PR7GZwv7MeApkz5JOSPHFVW3QTbzDJtzDIczkuWjeupLbckLyU5/gByftMg'.decode('base64').decode('zip')[32*y+x])]>>i&255 for i in 16,8,0]

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:

for y in range(32):
    for x in range(32):
        print red(x,y), blue(x,y), green(x,y)
Dillon Cower
fuente
Debería intentar agregar un color especial para repetir el valor de píxel anterior también. 588 caracteres base64 es mucho más grande que la cadena en mi respuesta (365 caracteres) y aunque zLib es excesivo aquí, debería dar un resultado similar, por lo que alrededor de 500 caracteres en total deberían ser posibles de esta manera.
schnaader
4

C ++, 631 caracteres; C - 613

Un codificador mtf unario base-92, C ++, 631 caracteres:

#define A(Z)int Z(int X,int Y){char*s="xdGe*V+KHSBBGM`'WcN^NAw[,;ZQ@bbZVjCyMww=71xK1)zn>]8b#3&PX>cyqy@6iL?68nF]k?bv/,Q`{i)n[2Df1zR}w0yIez+%^M)Diye{TC]dEY\\0,dU]s'0Z?+bo;7;$c~W;tvFl%2ruqWk$Rj0N[uP)fSjk?Tnpn_:7?`VbJ%r@7*MQDFCDo3)l#ln<kuRzzHTwCg&gYgSXtv\\m_Eb}zRK7JK<AZzOe}UX{Crk)SyBn;;gdDv=.j*O{^/q6)`lHm*YYrdM/O8dg{sKW#[email protected]#viYL$-<EU*~u5pe$r:`b)^dgXOJtf4";int*v,B=92,R=1,C=0,w[]={0,16354410,4671418,'aXL',7783255,5295994,'R@+','4k`',9975021,'NNv'};for(X+=Y*32+1;X--;)for(v=w;;){for(Y=*v++;R<B*B*B;C=C%R*B+*s++-35)R*=B;if(R/=2,C>=R){for(C-=R;--v>w;*v=v[-1]);*v=Y;break;}}return 255&Y
A(red);}A(blue)>>16;}A(green)>>8;}

Y la versión C de arriba (613 caracteres):

#define A (X,Y){char*s="xdGe*V+KHSBBGM`'WcN^NAw[,;ZQ@bbZVjCyMww=71xK1)zn>]8b#3&PX>cyqy@6iL?68nF]k?bv/,Q`{i)n[2Df1zR}w0yIez+%^M)Diye{TC]dEY\\0,dU]s'0Z?+bo;7;$c~W;tvFl%2ruqWk$Rj0N[uP)fSjk?Tnpn_:7?`VbJ%r@7*MQDFCDo3)l#ln<kuRzzHTwCg&gYgSXtv\\m_Eb}zRK7JK<AZzOe}UX{Crk)SyBn;;gdDv=.j*O{^/q6)`lHm*YYrdM/O8dg{sKW#[email protected]#viYL$-<EU*~u5pe$r:`b)^dgXOJtf4";int*v,B=92,R=1,C=0,w[]={0,16354410,4671418,'aXL',7783255,5295994,'R@+','4k`',9975021,'NNv'};for(X+=Y*32+1;X--;)for(v=w;;){for(Y=*v++;R<B*B*B;C=C%R*B+*s++-35)R*=B;if(R/=2,C>=R){for(C-=R;--v>w;*v=v[-1]);*v=Y;break;}}return 255&Y
red A;}blue A>>16;}green A>>8;}

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)

char* q="q^<A\">7T~pUN1 adz824K$5a>C@kC8<;3DlnF!z8@nD|9D(OpBdE#C7{yDaz9s;{gF[Dxad'[oyg\\,j69MGuFcka?LClkYFh=:q\\\\W(*zhf:x)`O7ZWKLPJsP&wd?cEu9hj 6(lg0wt\\g[Wn:5l]}_NUmgs]-&Hs'IT[ Z2+oS^=lwO(FEYWgtx),)>kjJSIP#Y?&.tx-3xxuqgrI2/m~fw \\?~SV={EL2FVrDD=1/^<r*2{{mIukR:]Fy=Bl.'pLz?*2a? #=b>n]F~99Rt?6&*;%d7Uh3SpLjI)_abGG$t~m{N=ino@N:";
#define I int
#define F(N) for(i=0;i<N;i++)
#define Z C=(C%T)*B+(*q++)-32
enum{B=95,H=1024,T=B*B*B};I p[B],v[B+H],n=3,*m=&v[B],R=T*B,C,i,j,y,c,x,w;void D(I P){w=(R>>11)*P;(y=C>=w)?R-=w,C-=w:R=w;while(R<T)R*=B,Z;}struct u{u(){F(4)Z;F(B)p[i]=H,v[i]=0;F(H){v[0]=m[i-1];v[1]=m[i-32];j=i;F(n){I&P=p[i];D(P);if(y){P-=P>>4;c=v[i];goto t;}else P+=H+H-P>>4;}c<<=7;for(x=-255;x<0;x+=x+y)D(H);v[n++]=c=x;t:m[i=j]=c;}}}d;I red(I x,I y,I z=0){return m[y*32+x]>>z&255;}
#define blue(x,y) red(x,y,8)
#define green(x,y) red(x,y,16)

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

Shelwien
fuente
3

C ++ - 1525 1004 964 caracteres

#define e (int x,int y){for(i=g=0;i<702;i=i+2)for(j=48;j<d[i];++j)c[g++]=d[i+1]-48;return 255&z[c[x+y*32]]
int i,g,j,z[]={0,7010700,12207943,5005656,5732035,8016079,2839104,6304875,15570996,7753294},c[1024];
char*d="3031;23322337261524453223310625132101214103453101233722172643310323342102521229492333210352112241036141014821042552621241014161016141024121022103210151015104526211034361034726510352625107441:530855425201511551045378554>55755312410242035201510528725212044451015411032:73135216561321012171017101725313581125152572531358122415257257110213310131231422022172025105110315322103210623815203110113053521053223817506920721013361322282530991062101213361322282520491049682224133614121028101510291029;812341023342835694810582018841018356978194810842835193329781019482410542835192310193668399428454319362928102829843845331019263028101330441014382035104369285338101810284536334910291018534820283546891019102943883536";
int red e>>16;}
int blue e>>8;}
int green e;}

Creó 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.

Scott Logan
fuente
¿Por qué no usas C? En C, es posible eliminar el nombre de tipo de una declaración si es intasí (se int f(int x,int y)convierte así f(x,y).
FUZxxl
@FUzxxl, sí, C casi siempre será más corto que C ++, pero en realidad no uso C diariamente y no conozco todos sus matices que se pueden usar para reducir la longitud. No me molesta tratar de ganar de todos modos, solo trato de superar cualquier otra respuesta de C ++.
Scott Logan
3

Javascript, 696694 caracteres

Gracias 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.

for(b=i=a=[];a&15||(a=atob("AxMrMyIzJxYlRDUiMwEmFSMBIUEBQzUBITMnEidGMwEjMyQBUhIi
SSkzIwFTEiFCAWNBAUEoASRVYhJCAUFhAWFBAUIhASIBIwFRAVEBVGISAUNjAUMnVgFTYlIBRxRaA1hF
UgJREVUBVHNYRV51VRNCAUICUwJRASV4UhICRFQBURQBI3oTUxJWFiMBIXEBcQFxUhNTGCEVJXVSE1MY
IhQldVIXARIzATEhEyQCInECUgEVARM1IgEjASaDUQITAREDNSUBNSKDcQWWAicBMWMxIoJSA5kBJgEh
MWMxIoJSApQBlIYiQjFjQSEBggFRAZIBkoshQwEyQ4JTloQBhQKBSAGBU5aHkYQBSIJTkTOShwGRhEIB
RYJTkTIBkWOGk0mCVDSRY5KCAYKSSINUMwGRYgOCATEDRAFBgwJTATSWgjWDAYEBglRjM5QBkgGBNYQC
glNkmAGRAZI0iFNjAQ==").charCodeAt(i++));b.push([0,16354410,4671418,6379596,77832
55,5295994,5390379,3435360,9975021,5131894][a-- >>4]));green=(red=function(c,d){
return b[32*d+c]>>this&255}).bind(16);blue=red.bind(8)

Nota: dividí el código para tener un poco de legibilidad. Tiene que estar en una línea para ejecutarse.

Código de prueba:

for(var y = 0; y < 32; ++y) {
    for(var x = 0; x < 32; ++x) {
        console.log(red(x, y), green(x, y), blue(x, y));
    }
}

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.

Copiar
fuente
Intente cambiar la matriz de paleta a [0,16354410,4671418,6379596,7783255,5295994,5390379,3435360,9975021,5131894]: esto ahorra 1 carácter y es el orden GBR en lugar de RGB.
schnaader
@schnaader Gracias. Me encantan esas micro optimizaciones :-) Editar: Incluso guardó 2 caracteres porque usé azul dos veces en mi fuente original
copie el
2

C ++, 1357 caracteres

int i,j,C[]={0,0,0,106,249,140,186,71,71,76,97,88,87,118,195,122,80,207,43,82,64,96,52,107,237,152,52,118,78,78},E[]={30,31,112,33,22,33,72,61,52,44,53,22,33,10,62,51,32,10,12,14,10,34,53,10,12,33,72,21,72,64,33,10,32,33,42,10,25,21,22,94,92,33,32,10,35,21,12,24,10,36,14,10,14,82,10,42,55,26,21,24,10,14,16,10,16,14,10,24,12,10,22,10,32,10,15,10,15,10,45,26,21,10,34,36,10,34,72,65,10,35,26,25,10,74,41,105,30,85,54,25,20,15,11,55,10,45,37,85,54,145,57,55,31,24,10,24,20,35,20,15,10,52,87,25,21,20,44,45,10,15,41,10,32,107,31,35,21,65,61,32,10,12,17,10,17,10,17,25,31,35,81,12,51,52,57,25,31,35,81,22,41,52,57,25,71,10,21,33,10,13,12,31,42,20,22,17,20,25,10,51,10,31,53,22,10,32,10,62,38,15,20,31,10,11,30,53,52,10,53,22,38,17,50,69,20,72,10,13,36,13,22,28,25,30,99,10,62,10,12,13,36,13,22,28,25,20,49,10,49,68,22,24,13,36,14,12,10,28,10,15,10,29,10,29,118,12,34,10,23,34,28,35,69,48,10,58,20,18,84,10,18,35,69,78,19,48,10,84,28,35,19,33,29,78,10,19,48,24,10,54,28,35,19,23,10,19,36,68,39,94,28,45,43,19,36,29,28,10,28,29,84,38,45,33,10,19,26,30,28,10,13,30,44,10,14,38,20,35,10,43,69,28,53,38,10,18,10,28,45,36,33,49,10,29,10,18,53,48,20,28,35,46,89,10,19,10,29,43,88,35,36,10};int*Q(int n){for(i=0;1;i++){for(j=0;j<E[i]/10;j++){if(!n)return&C[E[i]%10*3];n--;}}}
#define red(x,y) Q(x+32*y)[0]
#define blue(x,y) Q(x+32*y)[1]
#define green(x,y) Q(x+32*y)[2]

Desobuscado un poco:

int C[]={0,0,0,106,249,140,186,71,71,76,97,88,87,118,195,122,80,207,43,82,64,96,52,107,237,152,52,118,78,78},
int E[]={30,31,112,33,22,33,72,61,52,44,53,22,33,10,62,51,32,10,12,14,10,34,53,10,12,33,72,21,72,64,33,10,32,33,42,10,25,21,22,94,92,33,32,10,35,21,12,24,10,36,14,10,14,82,10,42,55,26,21,24,10,14,16,10,16,14,10,24,12,10,22,10,32,10,15,10,15,10,45,26,21,10,34,36,10,34,72,65,10,35,26,25,10,74,41,105,30,85,54,25,20,15,11,55,10,45,37,85,54,145,57,55,31,24,10,24,20,35,20,15,10,52,87,25,21,20,44,45,10,15,41,10,32,107,31,35,21,65,61,32,10,12,17,10,17,10,17,25,31,35,81,12,51,52,57,25,31,35,81,22,41,52,57,25,71,10,21,33,10,13,12,31,42,20,22,17,20,25,10,51,10,31,53,22,10,32,10,62,38,15,20,31,10,11,30,53,52,10,53,22,38,17,50,69,20,72,10,13,36,13,22,28,25,30,99,10,62,10,12,13,36,13,22,28,25,20,49,10,49,68,22,24,13,36,14,12,10,28,10,15,10,29,10,29,118,12,34,10,23,34,28,35,69,48,10,58,20,18,84,10,18,35,69,78,19,48,10,84,28,35,19,33,29,78,10,19,48,24,10,54,28,35,19,23,10,19,36,68,39,94,28,45,43,19,36,29,28,10,28,29,84,38,45,33,10,19,26,30,28,10,13,30,44,10,14,38,20,35,10,43,69,28,53,38,10,18,10,28,45,36,33,49,10,29,10,18,53,48,20,28,35,46,89,10,19,10,29,43,88,35,36,10};
int*Q(int n){
  for(int i=0;1;i++){
    for(int j=0;j<E[i]/10;j++){
      if(!n)return&C[E[i]%10*3];
      n--;
    }
  }
}
#define red(x,y) Q(x+32*y)[0]
#define blue(x,y) Q(x+32*y)[1]
#define green(x,y) Q(x+32*y)[2]

Ccontiene los valores RGB para los diez colores distintos de la imagen. Econtiene los datos para la imagen, donde cada elemento E[i]codifica un recuento repetido E[i]/10y un índice de color E[i]%10.

Keith Randall
fuente
+1 Puede eliminar algunos caracteres en el bucle: pastebin.com/2UY8H2qt
Pubby
1
Si cambia el nombre de su solución como C (no se requieren cambios de código) y convierte las definiciones en funciones sin nombres de tipo como int red(x,y){R Q(x+32*y)[0]}(only # define` return), es posible que pueda eliminar más caracteres.
FUZxxl
1
De alguna manera, esto es trampa, ya que el rojo, el azul y el verde no son funciones sino macros.
FUZxxl
1
Esto implementa una función y es más corto (1339 bytes). Tenga en cuenta que este programa probablemente solo sea válido en la antigua C: hpaste.org/65584
FUZxxl
Eliminé toda la información de tipo de la fuente. Todavía es válido C.
FUZxxl
1

Python 3 (589 caracteres)

import base64,zlib
red,blue,green=(lambda x,y,i=i:b'\xed\x984+R@j\xf9\x8cWv\xc3`4k\0\0\0\xbaGGzP\xcfvNNLaX'[zlib.decompress(base64.decodebytes(b'eJxtkgGSxSAIQxWN1vtfeEkEbf9sOmMdn0EEAZjZuFprxSCZpGlzrZUcL+5/jIbk+Phj0lr4MU58zEneUt8kiMlbQ63VwyfV0ZOq1cxxqyBvJJCRX3Cm5X7c+LJqQ63+j8N5kXkEIKeiXJl2jLP3/sPf6j257QSbwvmwy9ZD5ED6wd2GF+99J5WZ2S13h39aOetObrdO/A8f/3AdasbWrBEYnkVnzkhs0XpkA8YopUw9H/glEJw4ps49huuRgOzf8n6Iq85PCtneDxfhUCQ+F3JvdileT8FyxdfkCfhI+9yRCSAMlHxt+HLX3pd8+/0mh0MT9fPF8Xg6EeB52sc+WQlyxgA3XJycfi+D84X9GNCUKZ+E/JGjyqqbYJtZpo1ZhsN5ybJxPbXlluSlJMcf++8TIA=='))[32*y+x]*3+i]for i in(0,1,2))

Código de prueba

for y in range(32):
    for x in range(32):
        print(red(x,y), blue(x,y), green(x,y))

Basado en la solución de Dillon Cower

AMK
fuente
1

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.

// Colour map
$c=[0,16354410,4671418,6379596,7783255,5295994,5390379,3435360,9975021,5131894];

// Optimised RLE map
$r=array_merge(array_diff(range(10,89),[27,40,47,56,59,60,63,66,67,70,73,75,76,77,79,80,83,86]),[92,94,99,105,107,112,118,145]);

// Image data (base 70)
$e="CDsF<Fd]WPX<F0^VE0240GX02Fd;d_F0EFN0?;<onFE0H;2>0I404h0NZ@;>0460640>20<0E05050Q@;0GI0Gd`0H@?0eMqCjY?:51Z0QJjYu[ZD>0>:H:50Wk?;:PQ05M0ErDH;`]E0270707?DHg2VW[?DHg<MW[?c0;F032DN:<7:?0V0DX<0E0^K5:D01CXW0X<K7Ub:d03I3<A?Cp0^023I3<A?:T0Ta<>3I420A050B0Bt2G0=GAHbS0\:8i08Hbf9S0iAH9FBf09S>0YAH9=09IaLoAQO9IBA0ABiKQF09@CA03CP04K:H0ObAXK080AQIFT0B08XS:AHRm090BOlHI0";

// Expand image data
for($i=0;$i<352;$i++){$b=$r[ord($e[$i])-48];$l=(int)($b/10);while($l--)$d[]=$c[$b%10];}

// Colour retrieval functions
function red($x,$y){global$d;return$d[$x+$y*32]&0xff;}
function green($x,$y){global$d;return$d[$x+$y*32]>>8;}
function blue($x,$y){global$d;return($d[$x+$y*32]>>8)&0xff;}

Trozo de prueba:

for ($y=0;$y<32;$y++) {
    for ($x=0;$x<32;$x++) {
        printf("%d %d %d\n", red($x, $y), blue($x, $y), green($x, $y));
    }
}

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.

  1. Hay 10 colores únicos
  2. Los colores tienen longitudes de ejecución entre 1 y 14 (12 utilizados).
  3. Hay 120 combinaciones posibles.
  4. Solo se usan 70 combinaciones únicas de ejecución / color.

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:

  1. Investigue la codificación binaria del mapa RLE
  2. Encuentre una forma de reducir el tamaño de las funciones. globales una perra, pero no puede acceder a los índices de caracteres en las constantes.
  3. Experimente con el orden del índice de color para ver si el tamaño del mapa RLE se puede reducir con series secuenciales más largas de números
  4. Posibles optimizaciones específicas de 64 bits del mapa de color? (r0 << 56 | r1 << 48 | ...)?
  5. Experimente con RLE vertical para ver si da como resultado un conjunto más compacto de codificaciones.
  6. Codificación de área?
Leigh
fuente
1

C (gcc) , 602 bytes

P[]={0,6982905,0xba4747,5003361,5751670,8048464,2834514,6318900,0xed3498,7753294},X[1024],*i,r,w;
#define u(d)i=X;for(char*I="56s-8-8_TKCL-8!UJ7!#%!9L!#8_,_W8!78A!0,-us87!:,#/!;%!%i!AN1,/!%'!'%!/#!-!7!&!&!D1,!9;!9_X!:10!a@v&5lM0+&\"N!D<lMvNPN6/!/+:+&!Kn0,+CD!&@!7x(6:,XT7!#(!(!(06:h#JKP06:h-@KP0^!,8!$#6A+-(+0!J!6L-!7!U=&+6!\"5LK!L-=(I\\+_!$;$-305z!U!#$;$-30+H!H[-/$;%#!3!&!4!4y3#9!.93:\\G!Q+)k!):\\e*G!k3:*84e!*G/!M3:*.!*;[>u3DB*;43!34k=D8!*153!$5C!%=+:!B\\3L=!)!3D;8H!4!)LG+3:Ep!*!4Bo:;!";w=*I-33,*I++;)for(r=w/10+1;r--;*i++=P[w%10]>>d&255);x=X[y*32+x];
red(x,y){u(16)}green(x,y){u(8)}blue(x,y){u(0)}

Pruébalo en línea!

En mal estado

P[]={...},              The palette. Each entry is an integer on the form `RRGGBB`.
X[1024],                The buffer we unpack things into.
*i,r,w;                 Misc variables.
#define u(d)            Macro taking the number of bits to shift palette entries.
i=X;for(char*I="...";   Start at beginning of X for output, I is the encoded data.
                        Data was packed as ((R - 1) * 10) + P + 33, with R being
                        run-length and P the palette entry.
w=*I-33,*I++;)          Pick up encoded char, and check for end of data.
for(r=w/10+1;r--;       Get run-length from encoded byte.
*i++=P[w%10]>>d&255);   Get palette entry and extract colour given by d to store in X.
x=X[y*32+x];            Implicit return of the value at given coordinates.
red(x,y){u(16)}         The specific functions for each channel, calling u() for the
green(x,y){u(8)}        real work.
blue(x,y){u(0)}
gastropner
fuente