เข้ารหัสภาพภายในของแหล่งที่มา


10

ความท้าทายกอล์ฟคือการเข้ารหัสและบีบอัดภาพต่อไปนี้ภายในไฟล์ต้นฉบับ

ภาพ

ในการทำเช่นนี้คุณต้องเขียน 3 ฟังก์ชั่น: red, greenและblueที่ยอมรับพิกัด x / y ของภาพและส่งกลับค่าพิกเซล R / G / B ที่สอดคล้องกันระหว่าง 0-255

นี่คือรหัสทดสอบ 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));
}

และผลลัพธ์: http://pastebin.com/A770ckxL (คุณสามารถใช้มันเพื่อสร้างข้อมูลภาพของคุณ)

กฎและรายละเอียด:

  • นี่คือสนามกอล์ฟ
  • มีเพียงรหัส / ไฟล์ของคุณที่มีการตีกอล์ฟ - รหัสทดสอบแยกต่างหาก
  • ชุดอักขระที่ใช้คือ ASCII อย่างไรก็ตามสามารถใช้อักขระควบคุมในสตริงได้หากหนี (เช่น '\ n' และ '\ r' ฯลฯ )
  • ทุกอย่างจะต้องอยู่ในแหล่งที่มา - ไม่มีการโหลดไฟล์
  • เอาต์พุตของคุณจะต้องตรงกับเอาต์พุตตัวอย่าง หมายความว่าไม่มีการบีบอัดข้อมูล

ภาษา:

ปัญหาเขียนด้วย C / C ++ ในใจ แต่ฉันจะลบข้อ จำกัด เหล่านั้น ด้วยที่กล่าวว่าฉันจะยังคงแนะนำให้ใช้พวกเขา


4
หากไม่มีเหตุผลที่เฉพาะเจาะจงในการทำเช่นนั้นการแก้ไขคำถามเป็นภาษาใดภาษาหนึ่งนั้นไม่ได้รับการสนับสนุนอย่างสูง อะไรคือสาเหตุที่ทำไมคนเราต้องไม่ใช้ภาษาอื่น?
FUZxxl

3
หากวิธีแก้ปัญหามีความน่าสนใจน้อยลงอย่าโหวตให้เลย การห้ามใช้โซลูชัน "ง่อย" โดยการยกเว้นภาษานั้นเกินความจำเป็น
FUZxxl

2
หากคุณ จำกัด ชุดอักขระไว้ที่ ASCII (ซึ่งฉันถือว่าใช้ได้อย่างแน่นอน) เราจะใช้ Unicode hacks ได้อย่างไร สำหรับฐาน 64 คุณสามารถทำได้ใน C มาตรฐานเช่นเดียวกับภาษาอื่น ๆ มันเป็นเพียงจำนวนที่แตกต่างกันของรหัส wrapper - แต่ฉันชอบงาน
หยุดหมุนทวนเข็มนาฬิกา

1
อืมแล้วอักขระควบคุม ASCII 0-31 (และ 127) ล่ะ? ในทางเทคนิคพวกเขาเป็นส่วนหนึ่งของ ASCII แต่พวกเขาได้รับอนุญาตหรือไม่ และถ้าไม่ฉันหวังว่าจะมีข้อยกเว้นอย่างน้อยสำหรับตัวละคร LF (10) และอาจ CR (13) และ TAB (9) ด้วย
Ilmari Karonen

1
อืม ... ดังนั้นการอ่านเวอร์ชันใหม่ของคุณอย่างแท้จริงโซลูชั่นทั้งหมดจะต้องอยู่ในบรรทัดเดียวเนื่องจากไม่อนุญาตให้ป้อนฟีดบรรทัดที่ไม่ใช้ค่า Escape นั่นคือสิ่งที่คุณตั้งใจจริงเหรอ?
Ilmari Karonen

คำตอบ:


6

C, 796 754 712 703 692 685 682 670 666 662 656 648 ตัวอักษร

การเปลี่ยนแปลง:

  • 754-> 712: เพิ่มreturnเข้าไป#defineแทนที่ifด้วย?คำสั่ง (ขอบคุณ @FUZxxl) ลบออกintจากรายการพารามิเตอร์ฟังก์ชั่น
  • 712-> 703: สำเนาไร้ยางอายจาก bunnit อีกครั้ง :) ย้ายการสร้างภาพทั้งหมดไปไว้ใน #define
  • 703-> 692: ผสานp[]และh[]มี?:การปรับปรุงเพิ่มเติมบางอย่าง
  • 692-> 685: การเพิ่มbจึงiไม่จำเป็นอีกต่อไป m=bแทนที่จะเป็นm=11และn<2e3แทนที่จะเป็นi<356- สิ่งเหล่านี้ใกล้เคียงกับพฤติกรรมที่ไม่ได้กำหนด / ความเสียหายของหน่วยความจำ แต่ดูเหมือนว่าฉันโชคดี :)
  • 685-> 682: kตอนนี้ (32,16,8,4,2,1,0) แทน (5,4,3,2,1,0) Gotcha, DC;)
  • 682-> 670: Split p[]และh[]แปลงh[]ไปchar*- awwww มีคิตตี้ง่วงนอนอยู่ในนั้น^<+_=>-
  • 670-> 666: while=> for, l=l*2+...=>l+=l+...
  • 666-> 662: m=m>9?...=>c[n++]=m>9?...
  • 662-> 656: ลำดับบิตกลับด้านb[]ดังนั้นเราสามารถแมปไปที่ 64-127 แทน 0-63 และไม่ต้องการดัชนีบิตkอีกต่อไป ขอบคุณ@Piotr Tarsa แทนที่?:(ส่วนขยาย GCC) ||ด้วย ขอบคุณ@JamesB
  • 656-> 648: สำเนาไร้ยางอายจาก Shelwien :) (ค่าคงที่แบบหลายตัวอักษรสำหรับp[])

ภาพจะถูกแปลงเป็นสตริงที่คล้ายกับ Base64 (ASCII 37-100) โดยใช้การเข้ารหัส huffman เพื่อเข้ารหัสสี 0-9 โดยใช้ 3-6 บิตและสีพิเศษ 10 (พิกเซลเหมือนกับก่อนหน้านี้) โดยใช้เพียง 1 บิต

#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 #defineและภาพทั้งหมดจะถูกถอดรหัสอย่างสมบูรณ์ทุกครั้งที่มีการเรียกred/ green/ blueมีห้องพักสำหรับการปรับปรุงเพิ่มเติมดังนั้นคาดว่าจะมีการปรับปรุง :) ฉันไม่แน่ใจเกี่ยวกับการปฏิบัติตามโค้ดใช้ GCC 4.6.1 เพื่อรวบรวมและทดสอบ

การบีบอัดที่ชาญฉลาดฉันคิดว่าการเข้ารหัสทางเลขคณิตจะช่วยได้เนื่องจากการแจกแจงค่อนข้างเบาบาง แต่ค่าโสหุ้ยโค้ดอาจหนักเกินไปในกรณีนี้ LZW ควรทำผลงานได้ดีมากเช่นกัน สีค่อนข้างท้องถิ่นดังนั้นการเขียนโค้ดแบบปรับได้อาจเป็นความคิด

รุ่นตัวอักษรที่อ่านได้มากขึ้น 754 ความคิดเห็น:

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

ดีมากไม่น่าเชื่อว่าฉันไม่ได้คิดถึงการใช้ฐาน 64 ฉันคิดว่าคุณยังสามารถบันทึกตัวละครได้ไม่กี่ตัวโดยเฉพาะในวงนั้น ทำงานได้ดีใน VS2008 btw
Scott Logan

ฉันคิดว่าคุณสามารถลบสิ่งนั้นออกintจากรายการพารามิเตอร์เพื่อลบไบต์เพิ่มเติม
FUZxxl

เกี่ยวกับm=m>9?c[n-1]:m;เพื่อif(m>9)m=c[n-1];?
FUZxxl

และยัง: สำหรับif(k<0){j=b[i++]-37;k=5;}ทำไมไม่k>=0?:(j=b[i++]-37,k=5);? (รหัสนี้ใช้ส่วนขยาย C ของ gcc x=a?:bเหมือนกันx=a?a:bกับความแตกต่างที่ a ถูกประเมินเพียงครั้งเดียว
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 ตัวอักษร)

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]

เนื่องจากความท้าทายนี้เปิดให้ทุกคนทำไมไม่! เป็นเส้นทางเข้ารหัส zlib -> base64 ที่คุ้นเคยดังนั้นฉันจึงต้องขออภัยในสิ่งนั้น หวังว่ารายการที่มีรูปร่างหน้าตาของความเฉลียวฉลาดจะสั้นลง!

นี่คือตัวอย่างข้อมูลการทดสอบที่คล้ายคลึงกับของจริง:

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

คุณควรลองเพิ่มสีพิเศษเพื่อทำซ้ำค่าพิกเซลก่อนหน้าเช่นกัน 588 chars base64 มีขนาดใหญ่กว่าสตริงในคำตอบของฉัน (365 chars) และแม้ว่า zLib จะ overkill ที่นี่ควรให้ผลลัพธ์ที่คล้ายกันดังนั้นประมาณ 500 chars ควรเป็นไปได้ด้วยวิธีนี้
schnaader

4

C ++, 631 ตัวอักษร; C - 613

ตัวเข้ารหัส mtf แบบพื้นฐาน 92 ตัว, C ++, 631 ตัวอักษร:

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

และเวอร์ชั่น C ขึ้นไป (613 ตัวอักษร):

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

เพียงเพื่อรวมรายการที่มีฐานข้อมูล 95 และการเข้ารหัสทางคณิตศาสตร์ + ตัวแบบสถิติเชิงปรับตัว
โค้ดของ schnaader ใช้ข้อมูลได้ถึง 438 ตัวอักษรและสร้างได้เพียง 318 (311 โดยไม่มีการปิดบัง)
แต่ตามที่คาดไว้การเข้ารหัสทางคณิตศาสตร์นั้นซับซ้อนเกินไปสำหรับตัวอย่างเล็ก ๆ เช่นนี้

(นี่คือ 844 ตัวอักษร)

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)

การทดสอบ (จากเวอร์ชันฐาน -96 ก่อนหน้า):
http://codepad.org/qrwuV3Oy
http://ideone.com/ATngC

อย่างใดก็กินรหัส 7F ดังนั้นฉันต้องอัปเดตเป็นฐาน = 95


3

C ++ - 1525 1004 964 ตัวอักษร

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

สร้างอาร์เรย์ z ที่เก็บสีที่เป็นไปได้ทั้งหมดเป็นจำนวนเต็มเดียว (r << 16 | g << 8 | b) สร้างอาร์เรย์ d ซึ่งเก็บ {จำนวน, ค่า}, ค่าคือตำแหน่งในอาร์เรย์ z, จำนวนคือจำนวนพิกเซลต่อเนื่องที่มีค่านั้น (เช่น 3,0, หมายถึง colout t [0] จะปรากฏขึ้น 3 ถัดไป พิกเซลอาเรย์ของพิกเซลที่แท้จริง (c) จะถูกคำนวณทุกครั้งที่มีการเรียกว่าสีแดงค่าในอาร์เรย์นั้นจะเลื่อนไปทางขวาและ ANDed ตามความจำเป็นเพื่อให้ได้องค์ประกอบที่ถูกต้อง

ฉันอาจบันทึกอักขระเพิ่มอีกไม่กี่ (~ 50) โดยการกำหนดรูปแบบเพิ่มเติมจากอาร์เรย์ตามที่กำหนด

แก้ไข 1 - เปลี่ยนอาร์เรย์ d สำหรับอาร์เรย์ถ่านด้วยแต่ละค่าที่ชดเชยด้วย 48 ซึ่งหมายความว่าฉันสามารถแสดงว่ามันเป็นสตริงที่บันทึกภาระของจุลภาค

แก้ไข 2 - ใช้ฟังก์ชันที่มีขนาดใหญ่ขึ้นในคำสั่ง define


ทำไมคุณไม่ใช้ C ใน C เป็นไปได้ที่จะลบ type-name ออกจาก declaratrion ถ้าเป็นint( int f(int x,int y)จะกลายเป็นf(x,y)เช่นนั้น
FUZxxl

@Fzzxxl ใช่ C จะสั้นกว่า C ++ เกือบทุกครั้ง แต่ฉันไม่ได้ใช้ C ทุกวันและไม่ทราบความแตกต่างทั้งหมดที่สามารถใช้เพื่อลดความยาวได้ ฉันไม่ได้ใส่ใจกับการพยายามเอาชนะ แต่ฉันก็แค่พยายามเอาชนะคำตอบ C ++ อื่น ๆ
Scott Logan

3

Javascript, 696 694 ตัวอักษร

ขอบคุณ schnaader สำหรับ 696 -> 694

ฉันคิดว่ารูปแบบการเข้ารหัสที่แตกต่างกันซึ่งเป็นหลักคือการเข้ารหัสความยาวรันด้วยตารางการค้นหาสี มันใช้งานได้ดีมากเพราะมีน้อยกว่า 16 สีและพวกมันก็น้อยกว่า 16 ครั้งติดต่อกัน ดังนั้นความละเอียดของพิกเซลรวมถึงความยาวจึงเหมาะกับหนึ่งไบต์ ฉันใส่สีในส่วนสูงของไบต์และจำนวนในส่วนต่ำ

ในท้ายที่สุดสตริงเบส 64 กลายเป็นว่าจะนานกว่าที่ฉันคาดไว้ (472 ตัวอักษร) แต่โปรแกรมถอดรหัสนั้นสั้นมาก

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)

หมายเหตุ: ฉันแบ่งรหัสเพื่อให้สามารถอ่านได้เล็กน้อย มันจะต้องมีในบรรทัดเดียวที่จะเรียกใช้

รหัสทดสอบ:

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

ฉันคิดว่าตัวอย่างผลลัพธ์ที่ได้คือเอาท์พุทสีแดงเขียวน้ำเงิน (ไม่ใช่แดงน้ำเงินน้ำเงินเขียวเหมือนในรหัสทดสอบดั้งเดิม); มันใช้งานได้สำหรับฉันเช่นนั้น


ลองเปลี่ยนชุดจานสีเป็น[0,16354410,4671418,6379596,7783255,5295994,5390379,3435360,9975021,5131894]- จะช่วยประหยัด 1 ตัวอักษรและเป็นคำสั่ง GBR แทน RGB
schnaader

@ schnaader ขอบคุณ ฉันชอบการเพิ่มประสิทธิภาพขนาดเล็กเหล่านั้น :-) แก้ไข: แม้จะบันทึก 2 ตัวอักษรเพราะฉันใช้สีน้ำเงินสองครั้งในแหล่งข้อมูลดั้งเดิมของฉัน
คัดลอก

2

C ++, 1357 ตัวอักษร

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]

Deobfuscated เล็กน้อย:

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]

Cมีค่า RGB สำหรับสิบสีที่แตกต่างของภาพ Eมีข้อมูลสำหรับภาพที่แต่ละองค์ประกอบE[i]encodes ทั้งนับซ้ำและดัชนีสีE[i]/10E[i]%10


+1 คุณสามารถโกนตัวละครไม่กี่ตัวในลูป: pastebin.com/2UY8H2qt
Pubby

1
หากคุณเปลี่ยนโฉมโซลูชันของคุณเป็น C (ไม่ต้องเปลี่ยนรหัส) และเปลี่ยนการกำหนดเป็นฟังก์ชั่นที่ไม่มีชื่อประเภทเช่นint red(x,y){R Q(x+32*y)[0]}(only # define` return) คุณก็จะสามารถโกนตัวอักษรได้มากขึ้น
FUZxxl

1
อย่างไรก็ตามนี่คือการโกงเนื่องจากสีแดงสีน้ำเงินและสีเขียวไม่ใช่ฟังก์ชัน แต่เป็นมาโคร
FUZxxl

1
ใช้ฟังก์ชันและสั้นกว่า (1339 ไบต์) โปรดทราบว่าโปรแกรมนี้อาจใช้ได้เฉพาะในโปรแกรมเก่า C: hpaste.org/65584
FUZxxl

ฉันลบข้อมูลประเภททั้งหมดออกจากแหล่งที่มา ยังคงใช้ได้ C.
FUZxxl

1

Python 3 (589 ตัวอักษร)

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

รหัสทดสอบ

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

ขึ้นอยู่กับวิธีการแก้ปัญหาจาก Dillon Cower


1

PHP (5.4) - 822

ฉันได้กระทำนี้จงใจไม่ได้ใช้ใด ๆ ของฟังก์ชั่นการบีบอัด วิธีการแก้ปัญหานี้ยังไม่เสร็จฉันไม่แน่ใจว่าฉันเลิกใช้หรือไม่ฉันสามารถดูพื้นที่สำหรับการปรับปรุง แต่ฉันไม่สามารถหาเวลา / ความมุ่งมั่นที่จะปรับโครงสร้างสิ่งทั้งหมดในขณะนี้ดังนั้นฉันโพสต์สิ่งที่ฉัน มีจนถึงตอนนี้

บรรทัดใหม่ + ความคิดเห็นที่จะลบ 822 ไบต์

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

ทดสอบต้นขั้ว:

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

การบีบอัดข้อมูลภาพนั้นค่อนข้างดี แต่ฟังก์ชั่นในการดึงค่า RGB นั้นใช้โค้ด 1/4

ฉันใช้กลไกการเข้ารหัสความยาวแบบฐานที่กำหนดเอง 70 +

  1. มี 10 สีให้เลือก
  2. สีมีความยาวระหว่าง 1 ถึง 14 (ใช้ 12 ครั้ง)
  3. มีชุดค่าผสมที่เป็นไปได้ 120 ชุด
  4. มีชุดค่าผสมรัน / สีที่ไม่ซ้ำกันเพียง 70 รายการเท่านั้นที่ใช้จริง

ข้อมูลรูปภาพที่เข้ารหัสอ้างอิงดัชนีอาเรย์ของ RLE ซึ่งจะจัดทำดัชนีอาร์เรย์ของสี ฉันไม่แน่ใจว่าจะเพิ่มหรือลบค่าใช้จ่ายในการอ้างอิงสีโดยตรง

ไซน์มี 10 สี (0-9) RLEs run_length * 10 + colour_indexจะถูกเก็บเป็น ให้การเข้ารหัสที่หลากหลายระหว่าง 10 ถึง 145 โดยไม่ต้องทดลองปรับให้เหมาะสมตามการสั่งสี (เช่นฉันสามารถสร้างช่วงที่ 19 ถึง 140 ได้ด้วยการเลื่อนสี 0 ถึง 5, 5 ถึง 9 และ 9 ถึง 0 - แต่นี่อาจมีเอฟเฟกต์แบบน็อคออนอื่น ๆ )

คำตอบก่อนหน้านี้ระบุข้อมูลที่เข้ารหัสของพวกเขาคือ 472 ไบต์ ข้อมูลรูปภาพที่เข้ารหัสของฉันคือ 352 ไบต์ แต่แมป RLE / color ระดับกลาง (ซึ่งไม่ใช่การเข้ารหัสแบบไบนารี) คือ 129 ไบต์เพิ่มเติมรวมทั้งหมดที่ 481 (รวมถึงค่าใช้จ่ายเพิ่มเติมสำหรับการรวมสอง) อย่างไรก็ตามฉันสงสัยว่าวิธีการของฉันอาจขยายขนาดได้ดีกว่าสำหรับภาพขนาดใหญ่

ทำ:

  1. ตรวจสอบการเข้ารหัสไบนารีของแผนที่ RLE
  2. หาวิธีลดขนาดของฟังก์ชั่น globalเป็นผู้หญิงเลว แต่ไม่สามารถเข้าถึงดัชนีอักขระบนค่าคงที่ได้
  3. การทดสอบด้วยการจัดทำดัชนีสีเพื่อดูว่าสามารถลดขนาดแผนที่ RLE ได้หรือไม่ด้วยการใช้ตัวเลขที่ต่อเนื่องกันอีกต่อไป
  4. ศักยภาพการเพิ่มประสิทธิภาพเฉพาะของแผนที่สี 64 บิตหรือไม่ (r0 << 56 | r1 << 48 | ... )?
  5. ทดลองใช้ RLE แนวตั้งเพื่อดูว่ามีการเข้ารหัสที่กะทัดรัดขึ้นหรือไม่
  6. การเข้ารหัสพื้นที่?

1

C (gcc) , 602 ไบต์

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

ลองออนไลน์!

rundown

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)}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.