Nén mã của bạn trong một hình ảnh


17

Đây là một biến thể .

Giới thiệu

Tất cả chúng ta đều viết mã ngắn, vì một số lý do mơ hồ , nhưng bất cứ điều gì chúng ta làm, chúng sẽ chiếm ít nhất 144 pixel / byte (với phông chữ 12px). Nhưng điều gì sẽ xảy ra, nếu chúng ta mã hóa mã của mình bằng hình ảnh? Đây là nhiệm vụ của bạn ngày hôm nay.

Thử thách

Nhiệm vụ của bạn là đọc mã nguồn của riêng bạn (các phép tính không phù hợp được cho phép, ví dụ như đọc tệp nguồn theo nghĩa đen) và tạo một hình ảnh từ đó, bằng cách đặt các thành phần màu đỏ, xanh lục và xanh lam của pixel dựa trên ASCII giá trị của nhân vật.

Thí dụ:

Chúng tôi có chuỗi "Xin chào thế giới!"

Hello world!

Hãy chuyển đổi giá trị này thành giá trị ASCII:

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

Ánh xạ các giá trị RGB vào nó (Nếu độ dài của mã nguồn không chia hết cho 3, hãy sử dụng 0 làm các ký tự còn lại):

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

Sau đó chúng tôi tạo ra hình ảnh với diện tích nhỏ nhất trong số đó. Chúng tôi có 4 bộ giá trị RGB, vì vậy hình ảnh nhỏ nhất sẽ là hình ảnh 2 * 2, đi từ pixel trên cùng bên trái sang bên phải:

nhập mô tả hình ảnh ở đây

Và chúng ta có được hình ảnh có màu sắc khủng khiếp này (đã thay đổi kích thước, vì vậy ít nhất nó có thể nhìn thấy được, cũng chứng minh thực tế nó có thể nhỏ đến mức nào)

Quy tắc / Thông tin bổ sung

  • Không có đầu vào
  • Đầu ra phải là một tệp riêng biệt hoặc trong một cửa sổ riêng.
  • Đối với các ký tự đa dòng, chia nhân vật thành 2 byte.
  • Mã nguồn phải dài ít nhất 1 byte
  • Hình ảnh phải là một trong các kích thước có thể, có tỷ lệ chiều rộng / chiều cao gần nhất với 1
  • Số pixel trên hình ảnh chính xác phải là ceil (số byte / 3), không nên thêm pixel nào

Chấm điểm

Đây là một , vì vậy câu trả lời nhỏ nhất bằng byte sẽ thắng.


7
Đang chờ đệ trình của Piet ...: P
Rɪᴋᴇʀ 17/05/2016

3
"Hình ảnh nhỏ nhất" là gì? Diện tích nhỏ nhất? Đây sẽ không luôn luôn là một đường thẳng? Hình ảnh có phải là hình vuông không? Nếu vậy, làm thế nào để chúng ta đệm các pixel không vừa trong hình vuông? Bạn có thể cung cấp một số giải pháp mẫu? (Không nhất thiết phải có mã nguồn, chỉ cần bất kỳ chuỗi nào)
DJMcMayhem

2
Vẫn chưa siêu rõ. Cái nào quan trọng hơn, diện tích nhỏ nhất, hoặc tỷ lệ chiều rộng / chiều cao nhỏ nhất? Điều gì xảy ra nếu đó là ba hoặc bất kỳ số pixel chính nào khác? Tôi nên làm 1x3 (diện tích nhỏ nhất) hay 2x2 khi thiếu pixel (tỷ lệ nhỏ nhất)? Điểm thiếu đó nên là gì?
DJMcMayhem

3
Đây có phải trên hộp cát? Có vẻ như nó đã có thể sử dụng một thời gian ở đó.
Morgan Thrapp 17/05/2016

1
Không phải là tỷ lệ chiều rộng / chiều cao nhỏ nhất về mặt kỹ thuật sẽ luôn luôn như vậy height = Nwidth = 1? Tôi nghĩ bạn có nghĩa là chiều rộng / chiều cao gần nhất với 1.
Suever

Câu trả lời:


1

Trên thực tế, 12 byte

Q"P6 4 1 255

Hãy thử trực tuyến!

Chương trình này cũng hoạt động trong Nghiêm túc.

Chương trình này xuất ra một hình ảnh PPM , được chấp nhận theo mặc định .

Hình ảnh đầu ra (tăng 50 lần):

đầu ra

Giải trình:

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: Đầu ra phải là một tệp riêng biệt . Không phải điều này chỉ xuất nội dung tập tin sang STDOUT sao?
Adám

8

MATLAB, 81 72 69 byte

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

Điều này tạo ra một chức năng ẩn danh có thể được dán vào cửa sổ lệnh và chạy bằng cách sử dụng ans(). Khi chạy, điều này tạo ra một hình ảnh 23 pixel (một số nguyên tố) do đó biểu diễn vuông nhất là một mảng pixel đơn giản.

nhập mô tả hình ảnh ở đây

Giải trình

Khi được dán vào cửa sổ lệnh, hàm ẩn danh sẽ tự động gán cho biến ans. Sau đó, từ bên trong hàm ẩn danh, chúng tôi sử dụng:

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

mà đánh giá char(ans)trong không gian tên của cửa sổ lệnh chứ không phải trong không gian tên cục bộ của hàm ẩn danh. Do đó, nó có thể tự chuyển đổi hàm ẩn danh thành biểu diễn chuỗi.

Sau đó, chúng tôi có các hoạt động sau đây là đơn giản hơn:

%// 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 cho ansý tưởng!
flawr

Điều này không phải được chạy hai lần để làm việc? Lần đầu tiên, tôi mong muốn nó tạo ra một hình ảnh dựa trên giá trị anscho đến khi lần chạy đầu tiên được hoàn thành, điều này dẫn đến việc anstrở thành chính chức năng đó. Lần thứ hai, nó đang sử dụng mã "của chính nó" (thực ra, đó là mã của một hàm ẩn danh riêng biệt nhưng giống hệt nhau). Điều đó đang được nói, tôi không biết MATLAB, vì vậy tôi có thể sai.
Adám

2
@ Nᴮᶻ Đó là vẻ đẹp của việc sử dụng evalinđể gọi char(ans)trong không gian làm việc cơ sở. Chỉ evalinđược đánh giá vào thời gian chạy, mặc dù anskhông được xác định khi bạn dán nó vào cửa sổ lệnh, khi bạn gọi ans()để chạy chức năng ẩn danh này, ans được xác định và evalincuộc gọi bên trong chức năng ẩn danh có thể truy cập vào nó. Vì vậy, bạn không phải chạy nó hai lần. Nếu tôi có thể dựa vào nó được chạy hai lần, evalin('base', 'char(ans)')sẽ được thay thế bằng cách đơn giảnchar(ans)
Suever

4

Javascript (ES6) 324 312 309 byte

Tôi chắc chắn rằng điều này có thể được chơi golf một chút:

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'))}
  • tạo ra một bức tranh
  • xây dựng hình ảnh trong đó
  • Mở url dữ liệu cho hình ảnh trong tab mới

Các dòng mới để dễ đọc:

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

Đầu ra

JavaScript


Như tôi đã không chỉ định nó, bạn không cần phải làm cho nó tự động chạy.
Bálint

Ngoài ra, chỉ cần chèn một biến giả thay vì sử dụng các đoạn trống
Bálint

Đoạn trống? Ở đâu?
Shaun H

f=()=>{Ở đây, chỉ cần làm f=_=>, -1 byte, chỉ không sử dụng nó, javascript được gõ lỏng lẻo
Bálint

Ah tham số, hiện tại rời khỏi parens rẻ hơn so với xử lý không chia hết cho 3
Shaun H

3

Javascript ES6 - 216 byte

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)

Ung dung:

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

Lưu ý: ftrả về một khung vẽ.

Chạy ví dụ (giả sử có một <body>để nối thêm):

document.body.appendChild(f())

Nên đổ hình ảnh sau vào trang (phóng to):

QuineImage


Pixel cuối cùng hoàn toàn trống rỗng, bạn có thể tạo nó không, vậy tổng cộng là 71 pixel?
Bálint

@ Bálint Rất tiếc, không thấy phần pixel trống. Thật thú vị, nếu tôi cố gắng tạo ra hình ảnh 71x1, điều đó làm tăng số byte của tôi lên 214 và tình cờ, số điểm ảnh thành 72, là 9x8, lần lượt đưa số byte trở lại 213. Nó cũng làm hỏng tính toán kênh alpha . Giải pháp sạch nhất hiện tại đáp ứng tất cả các reqs là thêm 3 ký tự dự phòng vào giải pháp ...
Dendrobium

2

PowerShell v4, 64 byte

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

Nó lấy nội dung của tên tệp riêng của mình, tạo chuỗi dưới dạng mảng char, thêm một số tiêu đề PPM và đặt nội dung thành a.ppm làm đầu ra. 64 byte làm cho nó 11x2 pixel:

Nguồn PowerShell được mã hóa dưới dạng hình ảnh


1

Node.js, 63 byte

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

Xuất hình ảnh thành một tập tin có tên P6 trong PPM định dạng (P6).

Đây là bản hiển thị PNG (7x3 pixel):

nhập mô tả hình ảnh ở đây


1

PHP, 226 byte

Chơi gôn

<?$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);

Phiên bản ung dung

<?
// 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);

Nhập tập lệnh này vào một tệp có tên 'p.php' và chạy nó. Bạn cần phương pháp riêng để chạy tập lệnh PHP, bởi vì điều này đọc từ một tệp cục bộ.

Hình ảnh đầu ra:

mã màu


0

Java 511 ký tự

Độ dài của giải pháp dẫn đến một bức tranh lớn hơn rất tuyệt, bởi vì những bức ảnh này thực sự đẹp.

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

Lưu ý rằng có một dòng mới vô hình! Nó đọc tệp nguồn, phải là "Q.java" và tạo ra một hình ảnh "Q.png" trông như thế này:

Hình ảnh được tạo bởi mã

hoặc tỷ lệ 100x nhập mô tả hình ảnh ở đây


0

APL (Dyalog) , 33 byte

Yêu cầu ⎕IO←0mặc định trên nhiều hệ thống. Ngoài ra, AutoFormat nên tắt để bảo vệ chương trình chính xác như đã cho.

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

Hex B9 BA FD 4E 50 55 54 BB F8 0D 50 0D C2 CD 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 2C 2355 2395 41 56 2373 27 0D 026B 08 2363 27 2C 2283 233D 2395 4E 52 27 66 27

Tạo 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
Bạn lưu và thả vào đây để xem:mã hình ảnh

⎕NR'f'N ested R epresentation của chương trình f

⊃⌽ chọn phần tử cuối cùng (sáng đầu tiên của phần đảo ngược) (dòng)

'␍ɫ␉⍣', thêm bốn ký tự (kiểu, chiều rộng, chiều cao, tối đa)

⎕AV⍳ tìm các chỉ số tương ứng trong A tomic V ector (bộ ký tự

 định dạng như văn bản

'P', gửi thư

(... ) áp dụng các chức năng ngầm như sau:

 lấy toàn bộ đối số [và vào một]

⎕NPUTN ative [file,] Đặt [nó, với một tên tệp bao gồm]

 ký tự đầu tiên ("P")


Những gì codepage này giả định?
Bálint

@ Bálint Xem chỉnh sửa.
Adám

Làm thế nào đến hình ảnh kết quả là 42 pixel thay vì 14? Đây có phải là do "byte" của bạn tương ứng với các ký tự nhiều byte không?
Suever

@Suever Đã sửa. Cảm ơn.
Adám

BTW, tôi nghĩ, nếu phiên bản có trình biên dịch trước thử thách, thì đó là phiên bản hợp pháp.
Bálint

-1

Python, 81 byte

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

Đầu ra ở định dạng PPM.

Đây là những gì hình ảnh trông giống như:

Hình ảnh

Nhân rộng:

Nhân rộng


Tôi không thấy bạn tái sử dụngq
Maltysen

Nếu bạn sử dụng P6định dạng, bạn không cần phải chuyển đổi sang thứ tự. Ngoài ra, đối với RGB 8 bit, 255nên được sử dụng thay vì 256.
Mego

Nếu bạn chỉ sử dụng qmột lần, như có vẻ như bạn làm, hãy loại bỏ nhiệm vụ và thay thế trực tiếp - nó sẽ giúp bạn tiết kiệm ba byte.
Vụ kiện của Quỹ Monica

Có vẻ như bạn in nội dung tệp, nhưng OP cho biết Đầu ra phải là một tệp riêng biệt .
Adám

Xin chào, @QPaysTaxes nói print'P3\n9 3 256 '+' '.join(map(lambda x:str(ord(x)),open(__file__).read())). Đó là -4 byte, tho!
Erik the Outgolfer 19/05/2016
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.