Skompresuj kod na obrazie

17

To jest odmiana .

Wprowadzenie

Wszyscy piszemy krótki kod, ponieważ z jakichś niejasnych powodów , ale cokolwiek zrobimy, zajmie co najmniej 144 pikseli / bajt (czcionką 12px). Ale co by się stało, gdybyśmy kodowali nasz kod w obrazach? To jest dzisiaj twoje zadanie.

Wyzwanie

Twoim zadaniem jest odczytanie własnego kodu źródłowego (dozwolone są niepoprawne quiny, np. Dosłowne czytanie pliku źródłowego) i utworzenie z niego obrazu, poprzez ustawienie czerwonych, zielonych i niebieskich składników piksela na podstawie ASCII wartość znaku.

Przykład:

Mamy ciąg „Witaj świecie!”

Hello world!

Przekształćmy to w wartości ASCII:

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

Odwzoruj na nim wartości RGB (jeśli długości kodu źródłowego nie można podzielić przez 3, użyj 0 jako pozostałych znaków):

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

Następnie tworzymy obraz z najmniejszym obszarem z niego. Mamy 4 zestawy wartości RGB, więc najmniejszy obraz będzie obrazem 2 * 2, przechodzącym od lewego górnego piksela w prawo:

wprowadź opis zdjęcia tutaj

Otrzymujemy ten okropnie kolorowy obraz (przeskalowany, więc jest przynajmniej widoczny, dowodzi również, jak mały może być)

Zasady / Informacje dodatkowe

  • Nie ma danych wejściowych
  • Dane wyjściowe powinny znajdować się w osobnym pliku lub w osobnym oknie.
  • W przypadku znaków wielobajtowych podziel znak na 2 bajty.
  • Kod źródłowy musi mieć co najmniej 1 bajt
  • Obraz powinien być tym z możliwych rozmiarów, który ma najbliższy stosunek szerokości do wysokości do 1
  • Liczba pikseli na obrazie powinna dokładnie wynosić pułap (liczba bajtów / 3), nie należy dodawać żadnych dodatkowych pikseli

Punktacja

To jest , więc wygrywa najmniejsza odpowiedź w bajtach.

Bálint
źródło
7
Oczekiwanie na przesłanie Piet ...: P
Rɪᴋᴇʀ
3
Co to jest „najmniejszy obraz”? Najmniejszy obszar? Czy to nie zawsze byłaby linia prosta? Czy obraz musi być kwadratowy? Jeśli tak, to w jaki sposób wypełniamy piksele, które nie pasują do kwadratu? Czy możesz podać przykładowe rozwiązania? (Niekoniecznie z kodem źródłowym, tylko dowolny ciąg znaków)
DJMcMayhem
2
Nadal nie bardzo jasne. Co jest ważniejsze, najmniejszy obszar lub najmniejszy stosunek szerokości do wysokości? Co jeśli byłyby to trzy lub jakakolwiek inna liczba pierwsza? Czy powinienem zrobić 1x3 (najmniejszy obszar) lub 2x2 z brakującym pikselem (najmniejszy współczynnik)? Czym powinien być ten brakujący piksel?
DJMcMayhem
3
Czy to było na piaskownicy? Wygląda na to, że mógł tam poświęcić trochę czasu.
Morgan Thrapp
1
Nie jest najmniejszy stosunek szerokość / wysokość technicznie będzie zawsze height = Ni width = 1? Myślę, że masz na myśli szerokość / wysokość najbliższą 1.
Suever

Odpowiedzi:

1

Właściwie 12 bajtów

Q"P6 4 1 255

Wypróbuj online!

Ten program działa również na poważnie.

Ten program wyświetla obraz PPM , który jest domyślnie akceptowany .

Obraz wyjściowy (przeskalowany w górę 50x):

output

Wyjaśnienie:

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)
Mego
źródło
2
OP: Dane wyjściowe powinny być jako osobny plik . Czy to nie tylko wyświetla zawartość pliku do STDOUT?
Adám
8

MATLAB, 81 72 69 bajtów

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

Tworzy to anonimową funkcję, którą można wkleić do okna poleceń i uruchomić za pomocą ans(). Po uruchomieniu tworzy 23-pikselowy obraz (liczba pierwsza), dlatego najbardziej kwadratową reprezentacją jest prosta tablica pikseli.

enter image description here

Wyjaśnienie

Po wklejeniu do okna poleceń funkcja anonimowa automatycznie przypisuje się do zmiennej ans. Następnie z funkcji anonimowej korzystamy:

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

który ocenia char(ans)w obrębie przestrzeni nazw okna poleceń, a nie w lokalnej przestrzeni nazw funkcji anonimowej. Dlatego jest w stanie przekonwertować samą funkcję anonimową na reprezentację ciągu.

Następnie mamy następujące operacje, które są prostsze:

%// 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);
Suever
źródło
1
+1 za anspomysł!
flawr
Czy to nie musi być uruchamiane dwukrotnie, aby działać? Za pierwszym razem spodziewałbym się, że stworzy obraz oparty na wartości ansdo momentu zakończenia pierwszego uruchomienia, co spowoduje, ansże stanie się samą funkcją. Za drugim razem używa „własnego” kodu (właściwie to kod oddzielnej, ale identycznej anonimowej funkcji). Biorąc to pod uwagę, nie znam MATLAB, więc mogę się mylić.
Adám
2
@ Nᴮᶻ Na tym polega piękno evalinwywoływania char(ans)w podstawowym obszarze roboczym. evalinJest oceniana tylko w czasie wykonywania więc chociaż ansnie jest zdefiniowany po wklejeniu go w oknie poleceń, gdy dzwonisz ans()do uruchomienia tej funkcji anonimowej, ans jest zdefiniowane ievalin połączenia wewnątrz funkcji anonimowej do niego dostęp. Nie musisz więc uruchamiać go dwa razy. Gdybym mógł polegać na dwukrotnym uruchomieniu, evalin('base', 'char(ans)')zostałbym zastąpiony przezchar(ans)
Suever
4

JavaScript (ES6) 324 312 309 bajtów

Jestem pewien, że to może być trochę golfa:

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'))}
  • tworzy płótno
  • buduje w nim obraz
  • Otwiera adres URL danych dla obrazu w nowej karcie

Nowe linie dla czytelności:

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

Wynik

JavaScript

Shaun H.
źródło
Ponieważ nie określiłem tego, nie musisz uruchamiać go automatycznie.
Bálint
Po prostu wstaw zmienną fikcyjną zamiast pustych akapitów
Bálint
Puste akapity? Gdzie?
Shaun H
f=()=>{Tutaj, po prostu zrób f=_=>, -1 bajt, po prostu nie używaj, javascript jest luźno wpisany
Bálint
Ach parametry, prąd opuszczający parens jest tańszy niż obsługa nierównomiernie podzielna przez 3
Shaun H
3

JavaScript ES6 - 216 bajtów

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)

Nie golfowany:

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

Uwaga: f zwraca płótno.

Przykład uruchomienia (przy założeniu, że jest <body>do dołączenia):

document.body.appendChild(f())

Należy zrzucić następujący obraz na stronę (powiększenie):

QuineImage

Dendrobium
źródło
Ostatni piksel jest całkowicie pusty, czy możesz to zrobić, więc łącznie 71 pikseli?
Bálint
@ Bálint Ups, nie widział pustej części pikselowej. Co ciekawe, jeśli spróbuję zrobić obraz 71x1, to zwiększy moją liczbę bajtów do 214, a przy okazji, liczbę pikseli do 72, czyli 9x8, co z kolei spowoduje powrót liczby bajtów do 213. Zniszczy to również obliczenia kanału alfa . Obecnie najczystszym rozwiązaniem, które spełnia wszystkie wymagania, jest dodanie 3 zbędnych znaków do rozwiązania ...
Dendrobium
2

PowerShell v4, 64 bajty

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

Pobiera zawartość własnej nazwy pliku, rzutuje ciąg znaków jako tablicę char, dodaje nagłówek PPM i ustawia zawartość na a.ppm jako wynik. 64 bajty to 11 x 2 piksele:

Źródło PowerShell zakodowane jako obraz

TessellatingHeckler
źródło
1

Node.js, 63 bajty

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

Wysyła obraz do pliku o nazwie P6znajdującej się w PPM formacie (P6).

Oto wersja PNG (7 x 3 piksele):

wprowadź opis zdjęcia tutaj

Mwr247
źródło
1

PHP, 226 bajtów

Grał w golfa

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

Wersja bez golfa

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

Wprowadź ten skrypt do pliku o nazwie „p.php” i uruchom go. Potrzebujesz własnej metody uruchamiania skryptu PHP, ponieważ jest on odczytywany z pliku lokalnego.

Obraz wyjściowy:

oznaczone kolorami

Xanderhall
źródło
0

Znaki Java 511

Długość rozwiązania prowadzi do większego obrazu, który jest fajny, ponieważ te zdjęcia są naprawdę ładne.

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

Zauważ, że jest niewidoczny końcowy znak nowej linii! Odczytuje plik źródłowy, który musi być „Q.java” i tworzy obraz „Q.png”, który wygląda następująco:

Obraz wygenerowany przez kod

lub skalowane 100x wprowadź opis zdjęcia tutaj

Frozn
źródło
0

APL (Dyalog) , 33 bajty

Wymaga ⎕IO←0ustawienia domyślnego w wielu systemach. Ponadto Autoformatowanie powinno być wyłączone, aby zachować program dokładnie tak, jak podano.

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

Tworzy 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
Zapisujesz i upuszczasz tutaj, aby zobaczyć:obraz kodu

⎕NR'f'N a est R reprezentacja programu f

⊃⌽ wybierz ostatni (podświetlony pierwszy z odwróconego) elementu (linii)

'␍ɫ␉⍣', wstaw cztery znaki (typ pliku, szerokość, wysokość, maks.)

⎕AV⍳ znaleźć odpowiadające indeksy w A Tomic V wtryskiwacza (zestaw znaków

 sformatuj jako tekst

'P', przygotować list

() Zastosuj następującą funkcję ukrytą:

 weź cały argument [do]

⎕NPUTN atywny [plik,] Umieść [to z nazwą pliku składającą się z]

 pierwszy znak („P”)

Adám
źródło
Jaka strona kodowa to zakłada?
Bálint
@ Bálint Zobacz edycję.
Adám
Dlaczego wynikowy obraz ma 42 piksele zamiast 14? Czy to dlatego, że twoje „bajty” odpowiadają znakom wielobajtowym?
Suever
@Suever Naprawiono. Dzięki.
Adám
BTW, myślę, że jeśli wersja miała kompilator przed wyzwaniem, to jest legalna.
Bálint
-1

Python, 81 bajtów

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

Dane wyjściowe są w formacie PPM.

Oto jak wygląda obraz:

Wizerunek

Skalowane w górę:

Skalowane w górę

Loovjo
źródło
Nie widzę, żebyś q
używał
Jeśli używasz tego P6formatu, nie musisz konwertować na liczby porządkowe. Dodatkowo, w przypadku 8-bitowego RGB, 255zamiast 256.
Mego
Jeśli użyjesz tylko qraz, jak się wydaje, pozbądź się zadania i zastąp je bezpośrednio - pozwoli to zaoszczędzić trzy bajty.
Pozew Fund Moniki z
Wygląda na to, że drukujesz zawartość pliku, ale OP powiedział wynik powinien być osobnym plikiem .
Adám
Witaj, powiedział @QPaysTaxes print'P3\n9 3 256 '+' '.join(map(lambda x:str(ord(x)),open(__file__).read())). To -4 bajty!
Erik the Outgolfer