Comprime tu código en una imagen


17

Esta es una variación .

Introducción

Todos escribimos código corto, porque algunas razones oscuras , pero hagas lo que hagamos, ocuparán al menos 144 píxeles / byte (con una fuente de 12px). Pero, ¿qué pasaría si codificamos nuestro código en imágenes? Esta es tu tarea hoy.

Desafío

Su tarea es leer su propio código fuente (se permiten las citas incorrectas, por ejemplo, leer literalmente el archivo fuente) y crear una imagen a partir de él, configurando los componentes rojo, verde y azul de un píxel basado en el ASCII valor del personaje.

Ejemplo:

Tenemos la cadena "¡Hola mundo!"

Hello world!

Vamos a convertir esto a valores ASCII:

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

Asigne los valores RGB (si la longitud del código fuente no es divisible por 3, use 0 como 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 |
----------------------------------------------------

Luego creamos la imagen con el área más pequeña fuera de ella. Tenemos 4 conjuntos de valores RGB, por lo que la imagen más pequeña será una imagen 2 * 2, que va desde el píxel superior izquierdo a la derecha:

ingrese la descripción de la imagen aquí

Y obtenemos esta imagen terriblemente coloreada (redimensionada, por lo que es al menos visible, también demuestra el hecho de cuán pequeña puede ser)

Reglas / Información adicional

  • No hay entrada
  • El resultado debe ser como un archivo separado o en una ventana separada.
  • Para caracteres multibyte, divida el carácter en 2 bytes.
  • El código fuente debe tener al menos 1 byte de longitud
  • La imagen debe ser de los tamaños posibles, que tiene la relación ancho / altura más cercana a 1
  • El recuento de píxeles en la imagen debe ser exactamente ceil (byte count / 3), no se deben agregar píxeles adicionales

Puntuación

Este es un , por lo que gana la respuesta más pequeña en bytes.


77
Esperando una presentación de Piet ...: P
Rɪᴋᴇʀ

3
¿Qué es "la imagen más pequeña"? Área más pequeña? ¿No sería esto siempre una línea recta? ¿La imagen tiene que ser cuadrada? Si es así, ¿cómo rellenamos los píxeles que no caben en el cuadrado? ¿Podría proporcionar algunas soluciones de muestra? (No necesariamente con el código fuente, cualquier cadena)
DJMcMayhem

2
Todavía no está súper claro. ¿Cuál es más importante, el área más pequeña o la relación ancho / altura más pequeña? ¿Qué pasaría si fueran tres o cualquier otro número primo de píxeles? ¿Debo hacer 1x3 (área más pequeña) o 2x2 sin un píxel (relación más pequeña)? ¿Cuál debería ser ese píxel perdido?
DJMcMayhem

3
¿Estaba esto en la caja de arena? Parece que podría haber usado algún tiempo allí.
Morgan Thrapp

1
¿No es técnicamente la menor relación ancho / alto siempre será height = Ny width = 1? Creo que te refieres al ancho / alto más cercano a 1.
Suever

Respuestas:


1

En realidad, 12 bytes

Q"P6 4 1 255

Pruébalo en línea!

Este programa también funciona en serio.

Este programa genera una imagen PPM , que es aceptable por defecto .

Imagen de salida (aumentada 50x):

salida

Explicación:

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: La salida debe ser como un archivo separado . ¿Esto no solo envía el contenido del archivo a STDOUT?
Adám

8

MATLAB, 81 72 69 bytes

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

Esto crea una función anónima que se puede pegar en la ventana de comandos y ejecutar con ans(). Cuando se ejecuta, esto crea una imagen de 23 píxeles (primo), por lo tanto, la representación más cuadrada es una simple matriz de píxeles.

ingrese la descripción de la imagen aquí

Explicación

Cuando se pega en la ventana de comandos, la función anónima se asignará automáticamente a la variable ans. Luego, desde la función anónima, usamos:

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

que evalúa char(ans)dentro del espacio de nombres de la ventana de comandos en lugar de dentro del espacio de nombres local de la función anónima. Por lo tanto, puede convertir la función anónima en una representación de cadena.

Luego tenemos las siguientes operaciones que son más sencillas:

%// 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 por la ansidea!
flawr

¿No tiene que ejecutarse esto dos veces para que funcione? La primera vez, esperaría que creara una imagen basada en el valor que anstiene hasta que se complete la primera ejecución, lo que resulta en ansla función en sí. La segunda vez, está usando el código "propio" (bueno, en realidad, es el código de una función anónima separada pero idéntica). Dicho esto, no conozco MATLAB, así que puedo estar equivocado.
Adám

2
@ Nᴮᶻ Esa es la belleza de usar evalinpara llamar char(ans)en el espacio de trabajo base. El evalinsolo se evalúa en tiempo de ejecución, por lo que, aunque ansno está definido cuando lo pega en la ventana de comandos, cuando llama ans()para ejecutar esta función anónima, ans está definido y la evalinllamada dentro de la función anónima puede acceder a él. Por lo tanto, no tiene que ejecutarlo dos veces. Si pudiera confiar en que se ejecute dos veces, evalin('base', 'char(ans)')sería reemplazado por simplementechar(ans)
Suever

4

Javascript (ES6) 324 312 309 Bytes

Estoy seguro de que esto se podría jugar un poco:

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'))}
  • crea un lienzo
  • construye imagen en ella
  • Abre la URL de datos para la imagen en una pestaña nueva

Nuevas líneas de legibilidad:

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

Salida

JavaScript


Como no lo especifiqué, no es necesario que se ejecute automáticamente.
Bálint

Además, simplemente inserte una variable ficticia en lugar de usar párrafos vacíos
Bálint

Párrafos vacíos? ¿Dónde?
Shaun H

f=()=>{Aquí, simplemente f=_=>, -1 byte, simplemente no lo use, javascript está mal escrito
Bálint

Ah parámetros, la salida actual de los padres es más barata que el manejo no divisible por 3
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)

Sin golf:

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: fdevuelve un lienzo.

Ejemplo de ejecución (se supone que hay <body>que agregar):

document.body.appendChild(f())

Debería volcar la siguiente imagen en la página (ampliada):

QuineImage


El último píxel está completamente vacío, ¿puede hacerlo, por lo que son 71 píxeles en total?
Bálint

@ Bálint Whoops, no vi la parte de píxeles vacía. Curiosamente, si trato de hacer la imagen 71x1, eso aumenta mi recuento de bytes a 214 y, por cierto, el recuento de píxeles a 72, que es 9x8, lo que a su vez lleva el recuento de bytes a 213. También arruina el cálculo del canal alfa . La solución más limpia actual que cumple con todos los requisitos es agregar 3 caracteres redundantes a la solución ...
Dendrobium

2

PowerShell v4, 64 bytes

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

Obtiene el contenido de su propio nombre de archivo, convierte la cadena como una matriz de caracteres, agrega un encabezado PPM y establece el contenido en a.ppm como salida. 64 bytes lo hacen 11x2 píxeles:

Fuente de PowerShell codificada como imagen


1

Node.js, 63 bytes

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

Emite la imagen en un archivo llamado P6que está en formato PPM (P6).

Aquí hay una representación PNG (7x3 píxeles):

ingrese la descripción de la imagen aquí


1

PHP, 226 bytes

Golfed

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

Versión sin golf

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

Ingrese este script en un archivo llamado 'p.php' y ejecútelo. Necesita su propio método para ejecutar script PHP, ya que esto se lee desde un archivo local.

Imagen de salida:

codificado por color


0

Caracteres Java 511

La longitud de la solución conduce a una imagen más grande que es genial, porque estas imágenes son realmente agradables.

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

¡Tenga en cuenta que hay una nueva línea invisible al final! Lee el archivo fuente, que debe ser "Q.java" y crea una imagen "Q.png" que se ve así:

La imagen generada por el código.

o escalado 100x ingrese la descripción de la imagen aquí


0

APL (Dyalog) , 33 bytes

Requiere ⎕IO←0cuál es el predeterminado en muchos sistemas. Además, AutoFormat debe estar desactivado para preservar el programa exactamente como se indica.

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

Crea 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
Que guarda y suelta aquí para ver:imagen de código

⎕NR'f'N sado R ePresentation del programa f

⊃⌽ seleccione el último elemento (línea) del primer elemento (línea)

'␍ɫ␉⍣', anteponer los cuatro caracteres (tipo de archivo, ancho, alto, máximo)

⎕AV⍳ encontrar los índices correspondientes en el A Tomic V ector (el conjunto de caracteres

 formatear como texto

'P', anteponer una carta

(... ) aplique la siguiente función tácita:

 tomar todo el argumento [y en un]

⎕NPUTN ative [archivo,] Pon [it, con un nombre de archivo que consiste en]

 el primer caracter ("P")


¿Qué página de códigos supone esto?
Bálint

@ Bálint Ver editar.
Adám

¿Cómo es que la imagen resultante es de 42 píxeles en lugar de 14? ¿Es esto porque sus "bytes" corresponden a caracteres de varios bytes?
Suever

@Suever Fixed. Gracias.
Adám

Por cierto, creo que si la versión tenía un compilador antes del desafío, entonces es legal.
Bálint

-1

Python, 81 bytes

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

La salida está en formato PPM.

Así es como se ve la imagen:

Imagen

Ampliado:

Ampliado


No te veo reutilizandoq
Maltysen

Si usa el P6formato, no necesita convertir a ordinales. Además, para RGB de 8 bits, se 255debe utilizar en lugar de 256.
Mego

Si solo usa quna vez, como parece, elimine la asignación y sustitúyala directamente, le ahorrará tres bytes.
Financia la demanda de Mónica

Parece que imprime el contenido del archivo, pero OP dijo que la salida debería ser como un archivo separado .
Adám

Hola, dijo @QPaysTaxes print'P3\n9 3 256 '+' '.join(map(lambda x:str(ord(x)),open(__file__).read())). ¡Son -4 bytes, aunque!
Erik the Outgolfer
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.