Codifica un'immagine all'interno della fonte


10

La sfida del golf è codificare e comprimere la seguente immagine all'interno di un file sorgente.

Immagine

Per fare questo è necessario scrivere 3 funzioni: red, greene blueche accettano coordinate x / y dell'immagine e riportare il / G / valore di pixel corrispondente R B tra 0-255.

Ecco il codice di test 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));
}

E l'output: http://pastebin.com/A770ckxL (puoi usarlo per generare i tuoi dati di immagine)

Regole e dettagli:

  • Questo è un golf
  • Solo il tuo codice / file è golfato - il codice di test è separato
  • Il set di caratteri utilizzato è ASCII, tuttavia i caratteri di controllo nelle stringhe possono essere utilizzati solo se sono scappati (come '\ n' e '\ r', ecc.)
  • Tutto deve essere contenuto all'interno del sorgente - nessun caricamento di file
  • L'output deve corrispondere all'output di esempio. Questo significa compressione senza perdita.

Le lingue:

Il problema è stato scritto pensando a C / C ++, ma sto eliminando quelle restrizioni. Detto questo, consiglierò comunque di usarli.


4
Se non esiste un motivo specifico per farlo, è altamente scoraggiato porre una domanda in una lingua specifica. Qual è il motivo per cui non si devono usare altre lingue?
FUZxxl

3
Se una soluzione è meno interessante, non votarla. Vietare soluzioni "zoppe" escludendo le lingue è eccessivo.
FUZxxl

2
Se hai già limitato il set di caratteri a ASCII (che considero assolutamente ok), come possiamo usare gli hack Unicode? Per quanto riguarda la base 64, puoi farlo all'interno dello standard C e in qualsiasi altra lingua, solo quantità diverse di codice wrapper. - Ma mi piace il compito.
cessò di girare in senso antiorario il

1
Hmm, che dire dei caratteri di controllo ASCII 0-31 (e 127)? Tecnicamente, fanno parte di ASCII, ma sono ammessi? E se no, spero che venga fatta un'eccezione almeno per il personaggio LF (10), e forse anche CR (13) e TAB (9)?
Ilmari Karonen,

1
Ehm ... quindi, leggendo la tua nuova versione letteralmente, tutte le soluzioni devono essere su una riga, perché i feed di riga senza escape non sono consentiti. È davvero quello che intendi?
Ilmari Karonen,

Risposte:


6

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

changelog:

  • 754-> 712: aggiunto returna #define, sostituendo ifcon ?istruzioni (grazie a @FUZxxl), rimuovendo intdall'elenco dei parametri delle funzioni.
  • 712-> 703: Copia senza vergogna da bunnit :) Sposta l'intera creazione dell'immagine in #define
  • 703-> 692: uniti p[]e h[]alcuni altri ?:miglioramenti
  • 692-> 685: incrementare bin modo inon è più necessario. m=binvece di m=11e n<2e3invece di i<356- questi sono vicini a comportamenti indefiniti / corruzione della memoria, ma sembra che io sia fortunato :)
  • 685-> 682: kora è (32,16,8,4,2,1,0) anziché (5,4,3,2,1,0). Gotcha, DC;)
  • 682-> 670: diviso p[]e h[], convertito h[]in un char*- awwww, c'è un gattino assonnato in esso^<+_=>-
  • 670-> 666: while=> for, l=l*2+...=>l+=l+...
  • 666-> 662: m=m>9?...=>c[n++]=m>9?...
  • 662-> 656: ordine di bit invertito b[], quindi possiamo mappare a 64-127 invece di 0-63 e non abbiamo più bisogno dell'indice di bit k. Grazie @Piotr Tarsa . Sostituito ?:(estensione GCC) con ||. Grazie @JamesB
  • 656-> 648: copia spudorata di Shelwien :) (costanti multi-carattere per p[])

L'immagine viene convertita in una stringa simile a Base64 (ASCII 37-100), usando la codifica huffman per codificare i colori 0-9 usando 3-6 bit e un colore speciale 10 (il pixel è uguale al precedente) usando 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;}

Ho copiato due cose dalla risposta di bunnit, #definee l'intera immagine viene decodificata completamente ogni volta red/ green/ bluevengono chiamate. C'è ancora spazio per ulteriori miglioramenti, quindi aspettati alcuni aggiornamenti :) Non sono sicuro della conformità del codice, ho usato GCC 4.6.1 per compilare e testare.

Per quanto riguarda la compressione, penso che la codifica aritmetica sarebbe di aiuto in quanto la distribuzione è piuttosto distorta, ma forse l'overhead del codice sarebbe troppo pesante in questo caso. Anche LZW dovrebbe fare un ottimo lavoro. I colori sono abbastanza locali, quindi la codifica adattiva potrebbe essere un'idea.

Versione più leggibile di 754 caratteri con alcuni commenti:

#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;}

Molto bello, non posso credere di non aver pensato di usare la base 64. Penso che puoi comunque salvare parecchi personaggi, specialmente in quel loop. Funziona bene in VS2008 a proposito.
Scott Logan,

Penso che puoi rimuoverlo intdagli elenchi dei parametri per rimuovere altri byte.
FUZxxl

Che ne dici m=m>9?c[n-1]:m;di if(m>9)m=c[n-1];?
FUZxxl

E anche: if(k<0){j=b[i++]-37;k=5;}perché no k>=0?:(j=b[i++]-37,k=5);? (Questo codice utilizza un'estensione C di gcc, x=a?:bè lo stesso di x=a?a:b, con la differenza che a viene valutato una sola volta.
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 caratteri)

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]

Dal momento che questa sfida è ora aperta a tutti, perché no! È il familiare percorso di codifica zlib -> base64, quindi mi scuso per quello. Spero che una voce con una parvenza di ingegnosità sarà più breve!

Ecco uno snippet di prova analogo all'originale:

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

Dovresti provare ad aggiungere un colore speciale per ripetere anche il valore di pixel precedente. 588 caratteri base64 è molto più grande della stringa nella mia risposta (365 caratteri) e sebbene zLib sia eccessivo qui, dovrebbe dare un risultato simile, quindi in questo modo dovrebbero essere possibili circa 500 caratteri.
schnaader,

4

C ++, 631 caratteri; C - 613

Un codificatore mtf unario base 92, C ++, 631 caratteri:

#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#B3BLMiI8@-Zo-EsgE.R#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;}

E la versione C sopra (613 caratteri):

#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#B3BLMiI8@-Zo-EsgE.R#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;}

Giusto per includere una voce con dati di base 95 e codifica aritmetica + modello statistico adattivo.
Il codice di schnaader utilizza ~ 438 caratteri per i dati e il mio solo 318 (311 senza maschera).
Ma come previsto, la codifica aritmetica è troppo complicata per un piccolo campione come questo.

(Sono 844 caratteri)

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)

Test (dalla precedente versione base-96):
http://codepad.org/qrwuV3Oy
http://ideone.com/ATngC

In qualche modo SO mangia i codici 7F, quindi ho dovuto aggiornarlo su base = 95


3

C ++ - 1525 1004 964 caratteri

#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;}

Creato un array z che memorizza tutti i colori possibili come un unico numero intero (r << 16 | g << 8 | b). Creata una matrice d che memorizza {quantità, valore}, il valore è la posizione nella matrice z, la quantità è il numero di pixel consecutivi con quel valore. (Ovvero 3,0, significa che t [0] appare il prossimo 3 pixel La matrice effettiva di pixel (c) viene quindi calcolata ogni volta che viene chiamato il rosso.Il valore nella matrice viene quindi spostato a destra ed ANDed come necessario per ottenere il componente corretto.

Probabilmente potrei salvare qualche altro personaggio (~ 50) prendendo più schemi dall'array come definito.

Modifica 1 : modificato l'array d per un array di caratteri con ciascun valore offset di 48, il che significa che posso rappresentarlo come una stringa salvando un carico di virgole.

Modifica 2 : ha eliminato una parte maggiore delle funzioni nell'istruzione define.


Perché non usi C? In C, è possibile rimuovere il nome-tipo da un dichiaratrion se è int(così int f(int x,int y)diventa f(x,y).
FUZxxl

@Fuzxxl, sì, C sarà quasi sempre più corto di C ++, ma non uso davvero C su base giornaliera e non conosco davvero tutte le sfumature che possono essere utilizzate per ridurre la lunghezza. Non mi preoccupo di provare a vincere comunque, cerco solo di battere qualsiasi altra risposta C ++.
Scott Logan,

3

Javascript, 696 694 caratteri

Grazie a Schnaader per 696 -> 694.

Ho immaginato un diverso formato di codifica, che essenzialmente è la codifica Run-length con una tabella di ricerca dei colori. Funziona abbastanza bene, perché ci sono meno di 16 colori e appaiono meno di 16 volte di seguito; quindi ogni definizione di pixel inclusa la lunghezza si inserisce in un byte. Metto il colore nella parte alta del byte e il conteggio nella parte bassa.

Alla fine, la stringa base64 si è rivelata più lunga di quanto mi aspettassi (472 caratteri), ma il programma di decodifica è davvero breve.

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: ho diviso il codice per avere un po 'di leggibilità. Deve essere su una riga per funzionare.

Codice di prova:

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));
    }
}

Penso che il risultato dell'esempio sia in realtà l'output di rosso, verde, blu (non rosso, blu, verde come nel codice di test originale); funziona comunque per me così.


Prova a cambiare l'array di palette in [0,16354410,4671418,6379596,7783255,5295994,5390379,3435360,9975021,5131894]: questo salva 1 carattere ed è in ordine di GBR invece di RGB.
schnaader,

@schnaader Grazie. Adoro queste micro-ottimizzazioni :-) Modifica: ha persino salvato 2 caratteri perché ho usato il blu due volte nella mia fonte originale
copia il

2

C ++, 1357 caratteri

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]

Deo-offuscato un po ':

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 i valori RGB per i dieci colori distinti dell'immagine. Econtiene i dati per l'immagine, in cui ogni elemento E[i]codifica sia un conteggio ripetuto E[i]/10che un indice di colore E[i]%10.


+1 Potresti radere alcuni personaggi nel loop: pastebin.com/2UY8H2qt
Pubby

1
Se rinominate la vostra soluzione come C (non sono necessarie modifiche al codice) e trasformate le definizioni in funzioni senza digitare nomi come int red(x,y){R Q(x+32*y)[0]}(only # define` return), allora potreste essere in grado di radere di più caratteri.
FUZxxl

1
In qualche modo, questo è barare, dal momento che rosso, blu e verde non sono funzioni ma macro.
FUZxxl

1
Questo implementa una funzione ed è più breve (1339 byte). Si noti che questo programma è probabilmente valido solo nella vecchia C: hpaste.org/65584
FUZxxl

Ho rimosso tutte le informazioni sul tipo dalla fonte. È ancora valido C.
FUZxxl

1

Python 3 (589 caratteri)

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))

Codice di prova

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

Basato sulla soluzione di Dillon Cower


1

PHP (5.4) - 822

L'ho fatto deliberatamente non usando nessuna delle funzioni di compressione integrate . Questa soluzione non è finita, non sono sicuro di aver rinunciato, posso vedere le aree da migliorare ma al momento non riesco a trovare il tempo / la forza di volontà per il refactoring dell'intera cosa, quindi sto postando ciò che finora.

Newline + commenti da rimuovere per 822 byte.

// 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;}

Test stub:

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 compressione dei dati immagine è piuttosto buona, ma le funzioni per recuperare i valori RGB occupano 1/4 del codice.

Sto usando un meccanismo di codifica base70 + run personalizzato.

  1. Ci sono 10 colori unici
  2. I colori hanno una lunghezza compresa tra 1 e 14 (12 utilizzati).
  3. Esistono 120 combinazioni possibili.
  4. Esistono attualmente solo 70 combinazioni colore / corsa uniche .

I dati di immagine codificati fanno riferimento all'indice di array di un RLE, che a sua volta indicizza l'array di colori. Non sono sicuro di quanto sovraccarico si aggiunge o sottrae facendo riferimento direttamente ai colori.

Sine ci sono 10 colori (da 0 a 9), le RLE sono memorizzate come run_length * 10 + colour_index. Fornire una gamma di codifiche tra 10 e 145 senza sperimentare ottimizzazioni basate sull'ordinamento dei colori. (cioè potrei fare un intervallo da 19 a 140 spostando i colori da 0 a 5, da 5 a 9 e da 9 a 0 - ma questo potrebbe avere altri effetti a catena)

Una risposta precedente afferma che i loro dati codificati sono 472 byte. I miei dati di immagine codificati sono 352 byte, ma la mappa RLE / colore intermedia (che non è codificata binaria) è di ulteriori 129 byte, il totale a 481. (così come l'overhead aggiuntivo per unire i due). Tuttavia, sospetto che il mio metodo potrebbe ridimensionarsi meglio per immagini più grandi.

FARE:

  1. Indaga sulla codifica binaria della mappa RLE
  2. Trova un modo per ridurre le dimensioni delle funzioni. globalè una cagna, ma non può accedere agli indici dei caratteri sulle costanti.
  3. Sperimenta l'ordine degli indici di colore per vedere se la dimensione della mappa RLE può essere ridotta con sequenze di numeri sequenziali più lunghe
  4. Potenziali ottimizzazioni specifiche a 64 bit della mappa dei colori? (r0 << 56 | r1 << 48 | ...)?
  5. Sperimenta con RLE verticale per vedere se risulta in un set più compatto di codifiche.
  6. Codifica area?

1

C (gcc) , 602 byte

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)}

Provalo online!

Corri giù

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)}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.