บีบอัดรหัสของคุณในภาพ


17

นี่คือรูปแบบ

บทนำ

เราทุกคนเขียนโค้ดสั้น ๆ เพราะเหตุผลบางอย่างที่คลุมเครือแต่ไม่ว่าเราจะทำอะไรจะใช้เวลาอย่างน้อย 144 พิกเซล / ไบต์ (ด้วยตัวอักษร 12px) แต่จะเกิดอะไรขึ้นถ้าเราจะเข้ารหัสรหัสของเราในภาพ? นี่คืองานของคุณวันนี้

ท้าทาย

งานของคุณคือการอ่านในซอร์สโค้ดของคุณเอง (อนุญาตให้ใช้ควินส์ที่ไม่เหมาะสมเช่นการอ่านไฟล์ต้นฉบับ) และสร้างภาพออกมาโดยการตั้งค่าส่วนประกอบสีแดงสีเขียวและสีน้ำเงินของพิกเซลตาม ASCII ค่าของตัวละคร

ตัวอย่าง:

เรามีสตริง "Hello world!"

Hello world!

มาแปลงค่านี้เป็นค่า ASCII:

72 101 108 108 111 32 119 111 114 108 100 33

จับคู่ค่า RGB กับมัน (หากความยาวของซอร์สโค้ดไม่สามารถหารด้วย 3 ให้ใช้ 0 เป็นตัวอักษรที่เหลือ):

 __________________________________________________
| R | G | B || R | G | B || R | G | B || R | G | B |
----------------------------------------------------
|72 |101|108||108|111|32 ||119|111|114||108|100|33 |
----------------------------------------------------

จากนั้นเราสร้างภาพโดยให้มีพื้นที่เล็กที่สุดออกมา เรามีค่า RGB 4 ชุดดังนั้นภาพที่เล็กที่สุดจะเป็นภาพ 2 * 2 จากพิกเซลด้านซ้ายไปด้านขวา:

ป้อนคำอธิบายรูปภาพที่นี่

และเราได้ภาพที่มีสีสุดขีด (ปรับขนาดแล้วดังนั้นจึงสามารถมองเห็นได้อย่างน้อยก็พิสูจน์ให้เห็นว่ามันมีขนาดเล็กแค่ไหน)

กฎ / ข้อมูลเพิ่มเติม

  • ไม่มีอินพุต
  • ผลลัพธ์ควรเป็นไฟล์แยกต่างหากหรือในหน้าต่างแยกต่างหาก
  • สำหรับอักขระหลายไบต์ให้แยกอักขระเป็น 2 ไบต์
  • ซอร์สโค้ดต้องมีความยาวอย่างน้อย 1 ไบต์
  • รูปภาพควรมีขนาดเท่าที่เป็นไปได้ซึ่งมีอัตราส่วนความกว้าง / ความสูงใกล้เคียงกับ 1
  • จำนวนพิกเซลของรูปภาพควรจะเท่ากับ (จำนวนไบต์ / 3) อย่างแน่นอนไม่ควรเพิ่มพิกเซลเพิ่มเติม

เกณฑ์การให้คะแนน

นี่คือดังนั้นคำตอบที่น้อยที่สุดในหน่วยไบต์ชนะ


7
กำลังรอการส่ง Piet ... : P
Rɪᴋᴇʀ

3
"ภาพที่เล็กที่สุด" คืออะไร? พื้นที่เล็กที่สุด? นี่จะไม่ใช่เส้นตรงหรือไม่? ภาพต้องเป็นรูปสี่เหลี่ยมจัตุรัสหรือไม่? ถ้าเป็นเช่นนั้นเราจะวางพิกเซลที่ไม่พอดีกับสี่เหลี่ยมได้อย่างไร คุณสามารถให้โซลูชันตัวอย่างได้ไหม? (ไม่จำเป็นต้องมีซอร์สโค้ดแค่สตริงใด ๆ )
DJMcMayhem

2
ยังไม่ชัดเจน พื้นที่ใดที่สำคัญที่สุดมีขนาดเล็กที่สุดหรืออัตราส่วนความกว้างต่อความสูงน้อยที่สุด ถ้ามันเป็นสามหรือจำนวนพิกเซลที่สำคัญอื่น ๆ ? ฉันควรทำ 1x3 (พื้นที่เล็กที่สุด) หรือ 2x2 โดยมีพิกเซลหายไปหรือไม่ พิกเซลที่ขาดหายไปควรเป็นอย่างไร
DJMcMayhem

3
มันเป็นแบบนี้หรือเปล่า? ดูเหมือนว่ามันจะใช้เวลาพอสมควร
Morgan Thrapp

1
ไม่ได้อัตราส่วนกว้าง / สูงที่เล็กที่สุดในทางเทคนิคไปได้เสมอheight = Nและwidth = 1? ฉันคิดว่าคุณหมายถึงความกว้าง / ความสูงที่ใกล้เคียงกับ 1 มากที่สุด
Suever

คำตอบ:


1

จริงแล้ว 12 ไบต์

Q"P6 4 1 255

ลองออนไลน์!

โปรแกรมนี้ยังทำงานในอย่างจริงจัง

โปรแกรมนี้เอาท์พุทภาพ PPMซึ่งเป็นที่ยอมรับโดยปริยาย

ภาพที่ส่งออก (เพิ่มขึ้น 50x):

เอาท์พุต

คำอธิบาย:

Q"P6 4 1 255 
Q             push source code
 "P6 4 1 255  push header for a 4x1 raw (type P6) 8-bit PPM image (the closing " is implicitly added at EOF)

2
OP: การส่งออกควรจะเป็นไฟล์แยกต่างหาก สิ่งนี้ไม่เพียงส่งเนื้อหาไฟล์ไปยัง STDOUT หรือไม่
อดัม

8

MATLAB, 81 72 69 ไบต์

@()image(shiftdim(reshape(evalin('base','char(ans)'),3,1,23)/255,1.))

ans()นี้จะสร้างฟังก์ชั่นที่ไม่ระบุชื่อซึ่งสามารถวางลงในหน้าต่างคำสั่งและเรียกใช้ เมื่อรันสิ่งนี้จะสร้างภาพขนาด 23 พิกเซล (สีที่ดีที่สุด) ดังนั้นการแทนค่าสี่เหลี่ยมจัตุรัสส่วนใหญ่จึงเป็นอาร์เรย์พิกเซลแบบง่าย

ป้อนคำอธิบายรูปภาพที่นี่

คำอธิบาย

ansเมื่อวางลงในหน้าต่างคำสั่งฟังก์ชั่นที่ไม่ระบุชื่อโดยอัตโนมัติจะกำหนดตัวเองให้กับตัวแปร จากภายในฟังก์ชั่นนิรนามเราใช้:

evalin('base', 'char(ans)')

ซึ่งประเมินchar(ans)ภายในเนมสเปซของหน้าต่างคำสั่งมากกว่าภายในเนมสเปซท้องถิ่นของฟังก์ชันที่ไม่ระบุชื่อ ดังนั้นจึงสามารถแปลงฟังก์ชันนิรนามเป็นสตริงแทนได้

จากนั้นเรามีการดำเนินการที่ตรงไปตรงมามากขึ้น:

%// Reshape the result into a 3 x 1 x 23 matrix where the first dimension is RGB
%// due to column-major ordering of MATLAB
R = reshape(string, 3, 1, 23);

%// Divide the result by 255. This implicitly converts the char to a double
%// and in order for RGB interpreted properly by MATLAB, doubles must be
%// normalized between 0 and 1.
R = R / 255;

%// Shift the dimensions to the left 1 to move the RGB channel values into
%// the third dimension. Note the extra decimal point. This is because it
%// is far shorter to lengthen the code by one byte than to pad the string
%// to give us a length divisible by 3
R = shiftdim(R, 1.);

%// Display the RGB image
image(R);

1
+1 สำหรับansแนวคิด!
ข้อบกพร่อง

สิ่งนี้ไม่ต้องทำงานสองครั้งหรือไม่ ครั้งแรกที่ฉันคาดหวังว่ามันจะสร้างภาพตามค่าที่ansได้จนกว่าการรันครั้งแรกจะเสร็จสมบูรณ์ซึ่งส่งผลให้ansกลายเป็นฟังก์ชั่นของตัวเอง ครั้งที่สองมันใช้รหัส "ของตัวเอง" (จริง ๆ แล้วมันเป็นรหัสของฟังก์ชั่นที่ไม่ระบุตัวตนที่แยกจากกัน แต่เหมือนกัน) ที่ถูกกล่าวว่าฉันไม่รู้ MATLAB ดังนั้นฉันอาจผิด
อดัม

2
@ Nᴮᶻนั่นคือความสวยงามของการใช้evalinการโทรchar(ans)ในพื้นที่ทำงานพื้นฐาน evalinการประเมินเฉพาะที่เวลาทำงานดังนั้นแม้ว่าansจะไม่ได้กำหนดไว้เมื่อคุณวางลงในหน้าต่างคำสั่งเมื่อคุณเรียกans()จะเรียกใช้ฟังก์ชั่นที่ไม่ระบุชื่อนี้ans จะถูกกำหนดและevalinโทรภายในฟังก์ชั่นที่ไม่ระบุชื่อสามารถเข้าถึงได้ ดังนั้นคุณไม่ต้องรันสองครั้ง ถ้าฉันสามารถพึ่งพามันได้ถูกเรียกใช้สองครั้งevalin('base', 'char(ans)')ก็จะถูกแทนที่ด้วยเพียงchar(ans)
Suever

4

Javascript (ES6) 324 312 309 ไบต์

ฉันแน่ใจว่านี่สามารถเล่นกอล์ฟได้เล็กน้อย:

f=()=>{s="f="+f;l=s.length/3;c=document.createElement('canvas');for(i=0;++i<l/i;l%i?0:w=i,h=l/w);c.s=c.setAttribute;c.s("width",w);c.s("height",h);(i=(t=c.getContext('2d')).createImageData(w,h)).data.map((a,b)=>i.data[b]=b%4<3?s.charCodeAt(b-~~(b/4)):255);t.putImageData(i,0,0);open(c.toDataURL('image/png'))}
  • สร้างผ้าใบ
  • สร้างภาพในนั้น
  • เปิด URL ข้อมูลสำหรับรูปภาพในแท็บใหม่

บรรทัดใหม่สำหรับการอ่านได้:

f=()=>{
    s="f="+f;l=s.length/3;
    c=document.createElement('canvas');
    for(i=0;++i<l/i;l%i?0:w=i,h=l/w);
    c.s=c.setAttribute;
    c.s("width",w);
    c.s("height",h);
    (i=(t=c.getContext('2d')).createImageData(w,h)).data.map((a,b)=>i.data[b]=b%4<3?s.charCodeAt(b-~~(b/4)):255);
    t.putImageData(i,0,0);
    open(c.toDataURL('image/png'))
}

เอาท์พุต

JavaScript


เนื่องจากฉันไม่ได้ระบุไว้คุณไม่จำเป็นต้องทำการเรียกใช้อัตโนมัติ
Bálint

นอกจากนี้เพียงแค่ใส่ตัวแปรจำลองแทนการใช้ย่อหน้าที่ว่างเปล่า
Bálint

ย่อหน้าว่างเปล่า ที่ไหน?
Shaun H

f=()=>{ที่นี่เพียงทำf=_=>-1 ไบต์ไม่ใช้มันจาวาสคริปต์พิมพ์อย่างหลวม ๆ
Bálint

พารามิเตอร์ Ah, การออกจาก parens ปัจจุบันมีราคาถูกกว่าการจัดการที่ไม่สามารถหารได้อย่างเท่าเทียมกันโดย 3
Shaun H

3

Javascript ES6 - 216 ไบต์

f=(  )=>((d=(x=(v=document.createElement`canvas`).getContext`2d`).createImageData(v.width=9,v.height=8)).data.set([..."f="+f].reduce((p,c,i)=>(c=c.charCodeAt(0),[...p,...i%3<2?[c]:[c,255]]))),x.putImageData(d,0,0),v)

Ungolfed:

f=(  )=>(                                           // define function f (extra spaces to account for missing pixel + alpha channel calculation)
 (d=(x=(v=document.createElement`canvas`).          // assign html5 canvas to v
          getContext`2d`).                          // assign graphics context to x
          createImageData(v.width=9,v.height=8)).   // create & assign ImageData to d
                                                    //   set width and height of both d and v
 data.set([..."f="+f].                              // get f's source, convert to array of chars
   reduce((p,c,i)=>(c=c.charCodeAt(0),              // convert char array to int array
                    [...p,...i%3<2?[c]:[c,255]]))), // insert alpha values 255
 x.putImageData(d,0,0),                             // draw source RGBA array to canvas
 v)                                                 // return canvas

หมายเหตุ: fส่งคืนผ้าใบ

ตัวอย่างการรัน (สมมติว่ามีการ<body>ต่อท้าย):

document.body.appendChild(f())

ควรถ่ายโอนรูปภาพต่อไปนี้ไปยังหน้า (ขยาย):

QuineImage


พิกเซลสุดท้ายนั้นว่างเปล่าทั้งหมดคุณสามารถสร้างมันขึ้นมาได้ดังนั้นมันจึงเป็นทั้งหมด 71 พิกเซล?
Bálint

@ Bálintอ๊ะไม่เห็นส่วนพิกเซลว่างเปล่า น่าสนใจพอถ้าฉันพยายามทำให้ภาพ 71x1 นั้นเพิ่มจำนวนไบต์ของฉันเป็น 214 และบังเอิญจำนวนพิกเซลเป็น 72 ซึ่งก็คือ 9x8 ซึ่งจะนำจำนวนไบต์กลับมาเป็น 213 อีกทั้งยังทำลายการคำนวณช่องอัลฟา . วิธีการแก้ปัญหาที่สะอาดที่สุดในปัจจุบันที่ตรงกับความต้องการทั้งหมดคือการเพิ่มตัวอักษรซ้ำซ้อน 3 ตัวลงในโซลูชัน ...
Dendrobium

2

PowerShell v4, 64 ไบต์

"P6 11 2 255"+[char[]](gc $MyInvocation.MyCommand.Name)|sc a.ppm

จะได้รับเนื้อหาของชื่อไฟล์ของตัวเองมันได้ปลดสตริงเป็นอาร์เรย์ถ่านเพิ่มส่วนหัวของ PPM บางส่วนและตั้งเนื้อหาเป็น a.ppm เป็นเอาท์พุท 64 ไบต์ทำให้พิกเซล 11x2:

PowerShell เข้ารหัสเป็นรูปภาพ


1

Node.js, 63 ไบต์

(F=x=>require('fs').writeFile('P6','P6 7 3 255 (F='+F+')()'))()

ส่งสัญญาณรูปภาพเป็นไฟล์P6ที่อยู่ในรูปแบบPPM (P6)

นี่คือการเรนเดอร์ PNG (7x3 พิกเซล):

ป้อนคำอธิบายรูปภาพที่นี่


1

PHP, 226 ไบต์

แข็งแรงเล่นกอล์ฟ

<?$b=strlen($w=join(file('p.php')));$z=imagecreatetruecolor(5,15);for($c--;++$c<$b+1|$i%3;$i%3?:$a=!imagesetpixel($z,$x%5,(int)$x++/5,$a))$a+=($c<$b?ord($w[$c]):0)*256**(2-$i++%3);header("Content-Type:image/png");imagepng($z);

เวอร์ชันที่ไม่ดี

<?
// Read the file into an array and join it together. Store the length of the resulting string.
$b=strlen($w=join(file('p.php')));

// Create the image. Our file is 226 bytes, 226/3 = 75 = 5 * 15
$z=imagecreatetruecolor(5,15);

// Loop through the script string, converting each character into a pixel.
// Once three characters have been converted, draw the pixel with the converted RGB value and reset the color to 0.
for($c--;++$c<$b+1|$i%3;$i%3?:$a=!imagesetpixel($z,$x%5,(int)$x++/5,$a))$a+=($c<$b?ord($w[$c]):0)*256**(2-$i++%3);

// Tell the program we're sending an image
header("Content-Type:image/png");

// And send it!
imagepng($z);

ป้อนสคริปต์นี้ลงในไฟล์ชื่อ 'p.php' และเรียกใช้ คุณต้องใช้วิธีการเรียกใช้สคริปต์ PHP ของคุณเองเพราะสิ่งนี้จะอ่านจากไฟล์ในเครื่อง

ภาพที่ส่งออก:

รหัสสี


0

Java 511 chars

ความยาวของการแก้ปัญหานำไปสู่ภาพที่ใหญ่กว่าซึ่งเท่ห์เพราะภาพเหล่านี้ดีมาก

import java.awt.image.*;import java.io.*;import java.nio.file.*;import javax.imageio.*; public class Q{public static void main(String[]a)throws Throwable{int w=19,h=9;byte[]e=Files.readAllBytes(Paths.get("Q.java"));String t=new String(e);while(t.length()%3!=0)t+='\0';BufferedImage I=new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);int r,c=r=0;for(int i=0;i<t.length();i++){I.setRGB(c,r,255<<24|t.charAt(i)<< 16|t.charAt(++i)<< 8|t.charAt(++i));if(++c==w){c=0;r++;}}ImageIO.write(I,"png",new File("Q.png"));}}

โปรดทราบว่ามีการขึ้นบรรทัดใหม่ที่มองไม่เห็น! มันอ่านไฟล์ต้นฉบับซึ่งต้องเป็น "Q.java" และสร้างรูปภาพ "Q.png" ซึ่งมีลักษณะดังนี้:

ภาพที่สร้างขึ้นโดยรหัส

หรือปรับขนาด 100x ป้อนคำอธิบายรูปภาพที่นี่


0

APL (Dyalog) 33 ไบต์

ต้องใช้⎕IO←0ซึ่งเป็นค่าเริ่มต้นในหลาย ๆ ระบบ นอกจากนี้การจัดรูปแบบอัตโนมัติควรปิดเพื่อรักษาโปรแกรมให้ตรงตามที่กำหนด

(⊂⎕NPUT⊃)'P',⍕⎕AV⍳'␍ɫ␉⍣',⊃⌽⎕NR'f'  

Hex B9 BA FD 4E 50 55 54 BB F8 0D 50 0D C2 ซีดี FD 41 56 B2 0D 03 0B 01 FF 0D C2 BB C8 FD 4E 52 0D 16 0D
Unicode 28 2282 2395 4E 50 55 54 2283 29 27 50 27 2 27 23C 2355 2395 41 56 2373 27 0D 026B 08 2363 27 2C 2283 233D 2395 4E 52 27 66 27

สร้างP: P3 11 1 255 185 186 253 78 80 85 84 187 248 13 80 13 194 205 253 65 86 178 13 3 11 1 255 13 194 187 200 253 78 82 13 22 13
ซึ่งคุณบันทึกและวางที่นี่เพื่อดู:ภาพรหัส

⎕NR'f'N ested R epresentation ของโปรแกรม

⊃⌽ เลือกองค์ประกอบสุดท้าย (จุดแรกขององค์ประกอบที่กลับด้าน) (บรรทัด)

'␍ɫ␉⍣', เพิ่มอักขระสี่ตัวก่อน (ประเภทไฟล์, ความกว้าง, ความสูง, สูงสุด)

⎕AV⍳ ค้นหาดัชนีที่เกี่ยวข้องใน A tomic V ector (ชุดอักขระ

 จัดรูปแบบเป็นข้อความ

'P', เติมจดหมาย

(...)  ใช้ฟังก์ชัน tacit ต่อไปนี้:

 รับอาร์กิวเมนต์ทั้งหมด [และเข้า]

⎕NPUTN ative [ไฟล์] ใส่ [มันด้วยชื่อไฟล์ประกอบด้วย]

 อักขระตัวแรก ("P")


เพจรหัสนี้ใช้อะไร?
Bálint

@ Bálintดูการแก้ไข
อดัม

ทำไมภาพที่ได้จึงมีขนาด 42 พิกเซลแทนที่จะเป็น 14 พิกเซล นี่เป็นเพราะ "ไบต์" ของคุณตรงกับอักขระหลายไบต์หรือไม่
Suever

@Suever คงที่ ขอบคุณ
อดัม

BTW ฉันคิดว่าถ้ารุ่นมีคอมไพเลอร์ก่อนที่จะท้าทายแล้วมันก็เป็นกฎหมายอย่างใดอย่างหนึ่ง
Bálint

-1

Python ขนาด 81 ไบต์

q=open(__file__).read()
print'P3\n9 3 256 '+' '.join(map(lambda x:str(ord(x)),q))

เอาต์พุตอยู่ในรูปแบบ PPM

นี่คือลักษณะที่ปรากฏของภาพ:

ภาพ

ขยายขึ้น:

ขยายขนาดขึ้น


ฉันไม่เห็นคุณกำลังนำมาใช้ซ้ำq
2559 เวลา 16:53

หากคุณใช้P6รูปแบบคุณไม่จำเป็นต้องแปลงเป็นเลขลำดับ นอกจากนี้สำหรับ RGB 8 บิตควรจะนำมาใช้แทน255 256
Mego

หากคุณใช้เพียงqครั้งเดียวตามที่ดูเหมือนว่าคุณจะกำจัดงานที่มอบหมายและแทนที่มันโดยตรง - มันจะช่วยให้คุณสามไบต์
คดีของกองทุนโมนิกา

ดูเหมือนว่าคุณพิมพ์เนื้อหาไฟล์ แต่ OP กล่าวว่าการส่งออกควรจะเป็นไฟล์แยกต่างหาก
อดัม

สวัสดี @QPaysTaxes print'P3\n9 3 256 '+' '.join(map(lambda x:str(ord(x)),open(__file__).read()))กล่าวว่า มันคือ -4 ไบต์!
Erik the Outgolfer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.