Kaynağın içindeki bir görüntüyü kodlama


10

Golf zorluğu, bir kaynak dosya içinde aşağıdaki görüntüyü kodlamak ve sıkıştırmaktır.

görüntü

Bunu yapmak için, 3 işlevler yazmak gerekir: red, greenve bluebu, görüntünün X / Y koordinatları kabul 0-255 arasındaki karşılık gelen R / G / B piksel değeri döndürür.

İşte C / C ++ test kodu:

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

Ve çıktı: http://pastebin.com/A770ckxL (görüntü verilerinizi oluşturmak için bunu kullanabilirsiniz)

Kurallar ve detaylar:

  • Bu bir golf
  • Yalnızca kodunuz / dosyanız golf oynamaktadır - test kodu ayrıdır
  • Kullanılan karakter kümesi ASCII'dir, ancak dizelerdeki kontrol karakterleri yalnızca çıkış karakterleri kullanıldığında kullanılabilir ('\ n' ve '\ r' vb.)
  • Her şey kaynağın içinde bulunmalıdır - dosya yüklenmiyor
  • Çıktınız örnek çıktıyla eşleşmelidir. Bu, yalnız sıkıştırma anlamına gelir.

Diller:

Sorun C / C ++ düşünülerek yazılmıştır, ancak bu kısıtlamaları kaldırıyorum. Bununla birlikte, onları kullanmanızı tavsiye ederim.


4
Bunu yapmak için özel bir neden yoksa, bir soruyu belirli bir dile düzeltmek kesinlikle önerilmez. Kişinin başka dilleri kullanmamasının nedeni nedir?
FUZxxl

3
Bir çözüm daha az ilginçse, oy vermeyin. Dilleri hariç tutarak "topal" çözümlerin yasaklanması aşırıdır.
FUZxxl

2
Karakter setini ASCII ile sınırlandırdıysanız (ki bu kesinlikle iyi olduğunu düşünüyorum), Unicode kesmek nasıl kullanabiliriz? Temel 64'e gelince, bunu standart C içinde ve diğer herhangi bir dilde yapabilirsiniz, sadece farklı miktarlarda sarıcı kodu. - Ama görevi seviyorum.
counterclockwis

1
Hmm, ASCII 0-31 (ve 127) kontrol karakterleri ne olacak? Teknik olarak, ASCII'nin bir parçasılar, ancak izin veriliyor mu? Ve değilse, umarım en azından LF karakteri (10) ve belki de CR (13) ve TAB (9) için bir istisna yapılır?
Ilmari Karonen

1
Şey ... yani, yeni sürümünüzü tam anlamıyla okumak için, tüm çözümlerin tek bir satırda olması gerekir, çünkü kaçışsız satır yayınlarına izin verilmez. Gerçekten istediğin bu mu?
Ilmari Karonen

Yanıtlar:


6

C, 796754 712703 6926856826670666664656648 karakter

Değişiklikler:

  • 754-> 712: Eklenen returniçin #defineyerine ifbirlikte ?kaldırarak, ifadeler (teşekkürler @FUZxxl) intlistesinden parametre fonksiyonlardan gelen.
  • 712-> 703: Bunnit'ten utanmaz kopya tekrar :) Tüm görüntü yaratmayı #define
  • 703-> 692: Birleştirilmiş p[]ve h[]bazı ?:iyileştirmeler
  • 692-> 685: artırılmıyor byüzden iartık gerekli değildir. m=byerine m=11ve n<2e3yerine i<356- bunlar tanımlanmamış davranışa / bellek bozulmasına yakın, ama şanslı görünüyorum :)
  • 685-> 682: k(5,4,3,2,1,0) yerine şimdi (32,16,8,4,2,1,0). Gotcha, DC;)
  • 682-> 670: Bölün p[]ve bir - awwww'ya h[]dönüştürüldü , içinde uykulu bir kedi varh[]char*^<+_=>-
  • 670-> 666: while=> for, l=l*2+...=>l+=l+...
  • 666-> 662: m=m>9?...=>c[n++]=m>9?...
  • 662-> 656: Ters bit sırası b[], 0-63 yerine 64-127 ile eşlenebilir ve kartık bit dizinine ihtiyaç duymazız . Teşekkürler @Piotr Tarsa . İle değiştirildi ?:(GCC uzantısı) ||. Teşekkürler @JamesB
  • 656-> 648: Shelwien'den utanmaz kopya :) (için çok karakterli sabitler p[])

Görüntü, 3-6 bit kullanarak 0-9 renkleri ve yalnızca 1 bit kullanarak özel bir renk 10'u (piksel öncekiyle aynıdır) kodlamak için huffman kodlaması kullanılarak Base64 benzeri bir dizeye (ASCII 37-100) dönüştürülür.

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

Bunnit'in cevabından iki şey kopyalandı #defineve red/ green/ blueher çağrıldığında tüm görüntünün kodu tamamen çözülüyor . Ek iyileştirme için biraz yer var, bu yüzden bazı güncellemeler bekliyoruz :) Kod uyumluluğu hakkında emin değilim, derlemek ve test etmek için GCC 4.6.1 kullanılır.

Sıkıştırma açısından, dağıtım oldukça çarpık olduğu için aritmetik kodlama yardımcı olacağını düşünüyorum, ancak belki bu durumda kod yükü çok ağır olurdu. LZW de çok iyi bir iş çıkarmalı. Renkler oldukça yereldir, bu nedenle uyarlanabilir kodlama bir fikir olabilir.

Bazı yorumlarla daha okunabilir 754 karakter versiyonu:

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

Çok güzel, 64 tabanını kullanmayı düşünmediğime inanamıyorum. Özellikle bu döngüde yine de birkaç karakter kaydedebileceğinizi düşünüyorum. VS2008 btw'de iyi çalışıyor.
Scott Logan

Ben intbiraz daha bayt kaldırmak için parametre listelerinden kaldırabilirsiniz düşünüyorum .
FUZxxl

Peki m=m>9?c[n-1]:m;için if(m>9)m=c[n-1];?
FUZxxl

Ve ayrıca: if(k<0){j=b[i++]-37;k=5;}neden olmasın k>=0?:(j=b[i++]-37,k=5);? (Bu kod, gcc bir Cı uzantısı kullanan x=a?:baynı x=a?a:bbir kere değerlendirilmesi farkıyla.
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 ( 684492 karakter)

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]

Bu meydan okuma herkese açık olduğu için neden olmasın! Bu tanıdık zlib -> base64 kodlama yolu, bu yüzden özür dilerim. Umarım bazı yaratıcılıklara sahip bir giriş daha kısa olacaktır!

İşte orijinaline benzer bir test snippet'i:

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

Önceki piksel değerini de tekrarlamak için özel bir renk eklemeyi denemelisiniz. 588 karakter base64, cevabımdaki diziden çok daha büyük (365 karakter) ve zLib burada aşırı yüklü olmasına rağmen, benzer bir sonuç vermeli, bu yüzden toplamda yaklaşık 500 karakter bu şekilde mümkün olmalıdır.
schnaader

4

C ++, 631 karakter; C - 613

Bir baz-92 tekli mtf kodlayıcı, C ++, 631 karakter:

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

Ve yukarıdaki C versiyonu (613 karakter):

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

Sadece taban-95 verileri ve aritmetik kodlama + uyarlanabilir istatistiksel model içeren bir giriş eklemek.
schnaader'ın kodu veri için ~ 438 karakter kullanır ve benimki sadece 318'dir (maskeleme olmadan 311).
Ancak beklendiği gibi, aritmetik kodlama böyle küçük bir örnek için çok karmaşıktır.

(Bu 844 karakter)

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)

Testler (önceki taban-96 sürümünden):
http://codepad.org/qrwuV3Oy
http://ideone.com/ATngC

Bir şekilde SO 7F kodları yiyor, bu yüzden base = 95'e güncellemek zorunda kaldım


3

C ++ - 1525 1004 964 karakter

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

Olası tüm renkleri tek bir tamsayı olarak saklayan bir z dizisi oluşturuldu. (R << 16 | g << 8 | b). {Miktar, değer} depolayan bir d dizisi oluşturuldu, değer z dizisindeki konum, miktar bu değere sahip ardışık piksel sayısıdır. (Yani 3,0, colout t [0] sonraki 3 Daha sonra, kırmızı her çağrıldığında gerçek piksel dizisi (c) hesaplanır.Daha sonra doğru bileşen elde etmek için dizideki değer sağa kaydırılır ve gerektiği şekilde AND edilir.

Ben muhtemelen daha fazla desen tanımlar olarak dizi dışına alarak birkaç karakter (~ 50) kaydedebilirsiniz.

Düzenle 1 - bir char dizisi için d dizisini, her bir değer 48 ile kaydırılarak değiştirildi, yani virgül yükünü kaydeden bir dize olarak gösterebilirim.

Düzenle 2 - define deyiminde işlevlerin daha büyük bir bölümünü aldı.


Neden C kullanmıyorsunuz? C gerçekleştirirken, gerek ise bir beyanla gelen tip adı çıkarmak mümkündür int(bu yüzden int f(int x,int y)olur f(x,y).
FUZxxl

@FUzxxl, evet C neredeyse her zaman C ++ 'dan daha kısa olacaktır, ancak C'yi günlük olarak kullanmıyorum ve uzunluğu azaltmak için kullanılabilecek tüm nüanslarını gerçekten bilmiyorum. Yine de kazanmaya çalışarak rahatsız değilim, sadece diğer C ++ cevaplarını yenmeye çalışıyorum.
Scott Logan

3

Javascript, 696 694 karakter

696 -> 694 için schnaader'a teşekkürler.

Aslında bir renk arama tablosu ile Çalışma uzunluğu kodlama olan farklı bir kodlama formatı düşündüm . Oldukça iyi çalışıyor, çünkü 16'dan az renk var ve arka arkaya 16 kattan daha az görünüyorlar; böylece uzunluk dahil her piksel tanımı bir bayta sığar. Rengi baytın yüksek kısmına ve sayımı düşük kısma koydum.

Sonunda, base64 dizesi beklediğimden daha uzun çıktı (472 karakter), ancak kod çözme programı gerçekten kısa.

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)

Not: Okunabilirliği biraz artırmak için kodu böldüm. Çalıştırmak için bir satırda olması gerekir.

Test kodu:

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

Örnek sonuç aslında kırmızı, yeşil, mavi çıktı (orijinal test kodunda olduğu gibi kırmızı, mavi, yeşil değil); zaten benim için böyle çalışıyor.


Palet dizisini şu şekilde değiştirmeye çalışın [0,16354410,4671418,6379596,7783255,5295994,5390379,3435360,9975021,5131894]- bu 1 karakteri kaydeder ve RGB yerine GBR sırasıdır.
schnaader

@schnaader Teşekkürler. Bu mikro-optimizasyonları seviyorum :-) Düzenleme: Hatta 2 karakter kaydetti çünkü benim orignial kaynağımda iki kez mavi kullandım
kopya

2

C ++, 1357 karakter

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]

Biraz koku giderildi:

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]

Cgörüntünün on farklı rengi için RGB değerlerini içerir. Eher bir öğenin E[i]hem tekrar sayısını hem de E[i]/10renk dizinini kodladığı resim verilerini içerir E[i]%10.



1
Çözümünüzü C olarak yeniden markalarsanız (kod değişikliği gerekmez) ve tanımlayıcıları int red(x,y){R Q(x+32*y)[0]}(only # define` gibi tür adlarına sahip işlevlere dönüştürürseniz return, daha fazla karakter tıraş edebilirsiniz.
FUZxxl

1
Her nasılsa, bu hile, çünkü kırmızı, mavi ve yeşil fonksiyonlar değil makrolar.
FUZxxl

1
Bu bir işlevi gerçekleştirir ve daha kısadır (1339 bayt). Bu programın büyük olasılıkla yalnızca düz eski C için geçerli olduğunu lütfen unutmayın: hpaste.org/65584
FUZxxl

Tüm tür bilgilerini kaynaktan kaldırdım. Hala geçerlidir C.
FUZxxl

1

Python 3 (589 karakter)

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

Test kodu

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

Dillon Cower'ın çözümüne dayanmaktadır


1

PHP (5.4) - 822

Bunu kasıtlı olarak herhangi bir yerleşik sıkıştırma işlevini kullanmadan yaptım . Bu çözüm bitmedi, pes etmediğimden emin değilim, iyileştirme alanlarını görebiliyorum ama şu anda her şeyi yeniden düzenlemek için zaman / irade bulamıyorum, bu yüzden ne gönderdiğimi gönderiyorum şimdiye kadar var.

822 bayt için yeni satırlar + yorumlar kaldırılacak.

// 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 saplaması:

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

Görüntü verilerinin sıkıştırılması oldukça iyidir, ancak RGB değerlerini alma işlevleri kodun 1 / 4'ünü alır.

Özel bir base70 + çalışma uzunluğu kodlama mekanizması kullanıyorum.

  1. 10 benzersiz renk var
  2. Renklerin çalışma uzunlukları 1 ile 14 arasındadır (12 kullanılır).
  3. 120 olası kombinasyon vardır.
  4. Aslında kullanılan sadece 70 benzersiz çalışma / renk kombinasyonu vardır.

Kodlanan görüntü verileri, RLE'nin dizi dizinini referans alır ve bu da renk dizisini indeksler. Bunun renklere doğrudan atıfta bulunarak ne kadar fazla yük eklediğinden veya çıkardığından emin değilim.

Sinüs 10 renk (0 ila 9) vardır, RLE olarak depolanır run_length * 10 + colour_index. Renk sırasına göre yapılan optimizasyonları denemeden 10 ila 145 arasında bir dizi kodlama vermek. (yani, 0 ila 5, 5 ila 9 ve 9 ila 0 renklerini hareket ettirerek 19 ila 140 aralığını yapabilirim - ancak bunun başka vuruntu efektleri olabilir)

Önceki bir yanıt kodlanmış verilerinin 472 bayt olduğunu belirtir. Kodlanmış görüntü verilerim 352 bayt, ancak ara RLE / renk haritası (ikili kodlanmış değil), toplam 481. (ayrıca ikiye katılmak için ek yükü) koyarak 129 bayt daha. Ancak yöntemimin daha büyük görüntüler için daha iyi ölçeklenebileceğinden şüpheleniyorum.

YAPMAK:

  1. RLE haritasının ikili kodlamasını araştırın
  2. Fonksiyonların boyutunu azaltmanın bir yolunu bulun. globalbir orospu, ancak sabitler üzerindeki karakter dizinlerine erişemiyor.
  3. RLE harita boyutunun daha uzun ardışık sayılarla küçültülüp küçülemeyeceğini görmek için renk dizini sıralamasıyla deneme yapın
  4. Renk haritasının potansiyel 64 bit spesifik optimizasyonu? (r0 << 56 | r1 << 48 | ...)?
  5. Daha kompakt bir kodlama seti ile sonuçlanıp sonuçlanmadığını görmek için dikey RLE ile denemeler yapın.
  6. Alan kodlaması?

1

C (gcc) , 602 bayt

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

Çevrimiçi deneyin!

Bitkin

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)}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.