Comprima seu código em uma imagem


17

Esta é uma variação .

Introdução

Todos nós escrevemos código curto, porque algumas razões obscuras , mas o que fazemos, ocupam pelo menos 144 pixels / byte (com uma fonte de 12px). Mas o que aconteceria se codificássemos nosso código em imagens? Esta é sua tarefa hoje.

Desafio

Sua tarefa é ler seu próprio código-fonte (são permitidos quines inadequados, por exemplo, literalmente ler o arquivo de origem) e criar uma imagem a partir dele, definindo os componentes vermelho, verde e azul de um pixel com base no ASCII valor do personagem.

Exemplo:

Nós temos a string "Olá, mundo!"

Hello world!

Vamos converter isso em valores ASCII:

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

Mapeie os valores RGB para ele (se o comprimento do código-fonte não for divisível por 3, use 0s como os caracteres restantes):

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

Em seguida, criamos a imagem com a menor área dela. Como temos 4 conjuntos de valores RGB, a menor imagem será uma imagem 2 * 2, passando do pixel superior esquerdo para a direita:

insira a descrição da imagem aqui

E obtemos essa imagem muito colorida (redimensionada, de modo que seja pelo menos visível, também comprova o tamanho da imagem)

Regras / Informações adicionais

  • Não há entrada
  • A saída deve ser como um arquivo separado ou em uma janela separada.
  • Para caracteres multibyte, divida o caractere em 2 bytes.
  • O código-fonte deve ter pelo menos 1 byte de comprimento
  • A imagem deve ser a dos tamanhos possíveis, com a maior relação largura / altura a 1
  • A contagem de pixels na imagem deve ser exatamente o teto (contagem de bytes / 3), nenhum pixel extra deve ser adicionado

Pontuação

Este é um , então a menor resposta em bytes vence.


7
Aguardando uma submissão de Piet ...: P
Rɪᴋᴇʀ 17/05

3
O que é "a menor imagem"? Menor área? Isso não seria sempre uma linha reta? A imagem precisa ser quadrada? Se sim, como inserimos pixels que não cabem no quadrado? Você poderia fornecer algumas soluções de amostra? (Não necessariamente com o código fonte, apenas qualquer string)
DJMcMayhem

2
Ainda não é super claro. Qual é a mais importante, menor área ou menor relação largura / altura? E se fossem três ou qualquer outro número primo de pixels? Devo fazer 1x3 (menor área) ou 2x2 com um pixel ausente (menor proporção)? Qual deve ser esse pixel ausente?
DJMcMayhem

3
Isso estava na caixa de areia? Parece que poderia ter usado algum tempo lá.
Morgan Thrapp 17/05

11
A menor relação largura / altura não será tecnicamente sempre height = Ne width = 1? Eu acho que você quer dizer largura / altura mais próxima de 1.
Suever

Respostas:


1

Na verdade, 12 bytes

Q"P6 4 1 255

Experimente online!

Este programa também funciona em sério.

Este programa gera uma imagem PPM , que é aceitável por padrão .

Imagem de saída (ampliada em 50x):

resultado

Explicação:

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: A saída deve ser como um arquivo separado . Isso não gera apenas o conteúdo do arquivo para STDOUT?
Adám

8

MATLAB, 81 72 69 bytes

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

Isso cria uma função anônima que pode ser colada na janela de comando e executada usando ans(). Quando executado, isso cria uma imagem de 23 pixels (primária), portanto, a representação mais quadrada é uma matriz simples de pixels.

insira a descrição da imagem aqui

Explicação

Quando colada na janela de comando, a função anônima se atribui automaticamente à variável ans. Então, de dentro da função anônima, usamos:

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

que avalia char(ans)no espaço de nomes da janela de comando e não no espaço de nomes local da função anônima. Portanto, é capaz de converter a própria função anônima em uma representação de seqüência de caracteres.

Depois, temos as seguintes operações que são mais diretas:

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

11
+1 para a ansideia!
Flawr 18/05/19

Isso não precisa ser executado duas vezes para funcionar? Na primeira vez, eu esperaria que ela criasse uma imagem com base no valor ansaté a primeira execução ser concluída, o que resulta em ansse tornar a própria função. Na segunda vez, ele está usando o código "próprio" (bem, na verdade, é o código de uma função anônima separada, mas idêntica). Dito isto, não conheço o MATLAB, por isso posso estar errado.
Adám

2
@ Nᴮᶻ Essa é a beleza de usar evalinpara chamar char(ans)no espaço de trabalho base. Ele evaliné avaliado apenas em tempo de execução, mesmo que ansnão esteja definido quando você o cola na janela de comando, quando você chama ans()para executar esta função anônima, ans é definido e a evalinchamada dentro da função anônima pode acessá-lo. Portanto, você não precisa executá-lo duas vezes. Se eu pudesse contar com ele sendo executado duas vezes, evalin('base', 'char(ans)')seria substituído por simplesmentechar(ans)
Suever

4

Javascript (ES6) 324 312 309 bytes

Tenho certeza de que isso poderia ser um pouco jogado:

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'))}
  • cria uma tela
  • constrói imagem nele
  • Abre o URL de dados para a imagem em uma nova guia

Novas linhas de legibilidade:

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

Resultado

Javascript


Como eu não o especifiquei, você não precisa executá-lo automaticamente.
Bálint 17/05

Além disso, basta inserir uma variável binária, em vez de usar parágrafos vazios
Bálint

Parágrafos vazios? Onde?
Shaun H

f=()=>{Aqui, basta fazer f=_=>, -1 byte, apenas não usá-lo, o javascript é vagamente digitado
Bálint

Ah parâmetros, corrente deixando os parênteses é mais barato do que a manipulação não divisível por três
Shaun H

3

Javascript ES6 - 216 bytes

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

Nota: fretorna uma tela.

Exemplo de execução (pressupõe que haja um <body>para anexar):

document.body.appendChild(f())

Deve despejar a seguinte imagem na página (ampliada):

QuineImage


O último pixel está completamente vazio, você pode fazê-lo, então tem 71 pixels no total?
Bálint

@ Bálint Ops, não vi a parte de pixel vazia. Curiosamente, se eu tentar fazer a imagem 71x1, isso aumenta minha contagem de bytes para 214 e, aliás, a contagem de pixels para 72, que é 9x8, o que por sua vez eleva a contagem de bytes para 213. Isso também prejudica o cálculo do canal alfa . A solução mais limpa atual que atende a todos os reqs é adicionar 3 caracteres redundantes para a solução ...
Dendrobium

2

PowerShell v4, 64 bytes

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

Ele obtém o conteúdo de seu próprio nome de arquivo, lança a string como uma matriz de caracteres, adiciona algum cabeçalho PPM e define o conteúdo como a.ppm como saída. 64 bytes tornam 11x2 pixels:

Fonte do PowerShell codificada como imagem


1

Node.js, 63 bytes

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

Envia a imagem para um arquivo nomeado P6que está no PPM formato (P6).

Aqui está uma representação PNG (7x3 pixels):

insira a descrição da imagem aqui


1

PHP, 226 bytes

Golfe

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

Versão ungolfed

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

Digite esse script em um arquivo chamado 'p.php' e execute-o. Você precisa de seu próprio método de execução de script PHP, porque este lê de um arquivo local.

Imagem de saída:

codificado por cores


0

Caracteres Java 511

O comprimento da solução leva a uma imagem maior, o que é legal, porque essas imagens são realmente legais.

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

Observe que há uma nova linha invisível à direita! Ele lê o arquivo de origem, que deve ser "Q.java" e cria uma imagem "Q.png", com a seguinte aparência:

A imagem gerada pelo código

ou 100x dimensionado insira a descrição da imagem aqui


0

APL (Dyalog) , 33 bytes

Requer ⎕IO←0qual é o padrão em muitos sistemas. Além disso, a AutoFormatação deve estar desativada para preservar o programa exatamente como fornecido.

(⊂⎕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

Cria 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 O
que você salva e solta aqui para ver:imagem de código

⎕NR'f'N ested R ePresentation do programa f

⊃⌽ escolha o último elemento (lit. primeiro do reverso) (linha)

'␍ɫ␉⍣', preceda os quatro caracteres (tipo de arquivo, largura, altura, max)

⎕AV⍳ encontrar índices correspondente na Uma Tomic V ector (o conjunto de caracteres

 formatar como texto

'P', anexar uma carta

() Aplique a seguinte função tácita:

 pegue o argumento inteiro [e entre em]

⎕NPUTN Ative [arquivo], Put [ele, com um nome que consiste em]

 o primeiro caractere ("P")


Que página de código isso assume?
Bálint 17/05

@ Bálint Ver edição.
Adám 17/05

Como a imagem resultante é de 42 pixels em vez de 14? Isso ocorre porque seus "bytes" correspondem a caracteres de vários bytes?
Suever

@Suever Fixed. Obrigado.
Adám 18/05/19

BTW, eu acho, se a versão tinha um compilador antes do desafio, então é legal.
Bálint

-1

Python, 81 bytes

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

A saída está no formato PPM.

É assim que a imagem se parece:

Imagem

Ampliados:

Ampliados


Eu não vejo você reutilizarq
Maltysen

Se você usar o P6 formato, não precisará converter em ordinais. Além disso, para RGB de 8 bits, 255deve ser usado em vez de 256.
Mego 19/05

Se você usar apenas quma vez, como parece, se livrar da tarefa e substituí-la diretamente - você economizará três bytes.
Fund Monica's Lawsuit

Parece que você imprimiu o conteúdo do arquivo, mas o OP disse: A saída deve ser como um arquivo separado .
Adám

Olá, disse @QPaysTaxes print'P3\n9 3 256 '+' '.join(map(lambda x:str(ord(x)),open(__file__).read())). São -4 bytes, tho!
Erik the Outgolfer
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.