Narysujmy Mona Lisę


39

W 2014 roku demoscener Jakub „Ilmenit” Dębski wydał demo 250-bajtowej (1) grafiki proceduralnej dla Atari XL o nazwie Mona . Rysuje następujący obrazek (2) :

Mona

Twoim zadaniem jest wygenerowanie dokładnie tego samego obrazu w wybranym języku.


(1) Podział: 136 bajtów danych + 114 bajtów kodu.
(2) Oryginalne zdjęcie to 128x96. Powyższa wersja została powiększona do 256 x 192. Kilka pikseli różni się od oryginału, ale jest to oczekiwany wynik z pseudokodem opisanym w tym wyzwaniu.

W jaki sposób?

To jest . Chociaż masz uprawnienia do korzystania z dowolnej metody, najlepsze wyniki najprawdopodobniej zostaną osiągnięte przy użyciu oryginalnego algorytmu, który opisano poniżej.

Uwaga : ten akapit nie jest specyfikacją, ale raczej ogólnym opisem. Szczegółowe informacje na temat algorytmu znajdują się w pseudokodzie i implementacji referencyjnej.

Obraz składa się z 64 pseudolosowych pociągnięć pędzla ( patrz ten film ), cyklicznie następujących kolorów (w formacie szesnastkowym RRGGBB):

COLOR = [ 0xFFE289, 0xE99E45, 0xA55A00, 0x000000 ]

Tło jest początkowo wypełnione czwartym kolorem (czarnym). Każde uderzenie jest krótsze niż poprzednie.

Generator pseudolosowy wykorzystuje rejestr przesunięcia liniowego (LFSR) na 32-bitowej liczbie całkowitej początkowo ustawionej na 0x7EC80000i XOR'ed 0x04C11DB7.

Każde uderzenie jest inicjowane 16-bitową wartością, która zastępuje najniższe bajty zarodka:

BRUSH = [
  0x030A, 0x37BE, 0x2F9B, 0x072B, 0x0E3C, 0xF59B, 0x8A91, 0x1B0B,
  0x0EBD, 0x9378, 0xB83E, 0xB05A, 0x70B5, 0x0280, 0xD0B1, 0x9CD2,
  0x2093, 0x209C, 0x3D11, 0x26D6, 0xDF19, 0x97F5, 0x90A3, 0xA347,
  0x8AF7, 0x0859, 0x29AD, 0xA32C, 0x7DFC, 0x0D7D, 0xD57A, 0x3051,
  0xD431, 0x542B, 0xB242, 0xB114, 0x8A96, 0x2914, 0xB0F1, 0x532C,
  0x0413, 0x0A09, 0x3EBB, 0xE916, 0x1877, 0xB8E2, 0xAC72, 0x80C7,
  0x5240, 0x8D3C, 0x3EAF, 0xAD63, 0x1E14, 0xB23D, 0x238F, 0xC07B,
  0xAF9D, 0x312E, 0x96CE, 0x25A7, 0x9E37, 0x2C44, 0x2BB9, 0x2139
];

Wartości te są również używane do ustawienia nowej pozycji pędzla na początku obrysu (bx, by) : bx jest podawany przez najmniej znaczący bajt, a przez przez najbardziej znaczący bajt.

Kierunek skoku jest podany przez bity # 1 i # 7 nasion. (Zobacz instrukcję SWITCH w pseudokodzie).

Pseudo kod

Poniżej jest algorytm w pseudo-kodzie, zakładając 0 indeksowane tablice, tam gdzie AND, ORi XORśrednie operacje bitowe.

seed = 0x7EC80000
dir = 0x00

FOR part = 0 TO 63
  word = BRUSH[part]
  seed = (seed AND 0xFFFF0000) OR word
  bx = word AND 0xFF
  by = (word >> 8) AND 0xFF

  FOR len = 0 TO (64 - part) * 32 - 1
    carry = seed AND 0x80000000
    seed = (seed << 1) AND 0xFFFFFFFF

    IF carry
      seed = seed XOR 0x04C11DB7
      dir = seed AND 0xFF
    ENDIF

    SWITCH dir AND 0x82
      CASE 0x00:
        by = (by + 1) AND 0x7F
      ENDCASE
      CASE 0x02:
        bx = (bx + 1) AND 0x7F
      ENDCASE
      CASE 0x80:
        by = (by - 1) AND 0x7F
      ENDCASE
      CASE 0x82:
        bx = (bx - 1) AND 0x7F
      ENDCASE
    ENDSWITCH

    drawPixel(bx, by, COLOR[part AND 3])
  ENDFOR
ENDFOR

Realizacja referencyjna

Poniżej znajduje się niezawierająca odniesienia implementacja w JavaScript.

Tutaj możesz także zobaczyć animowaną wersję .

Wyjaśnienie i zasady

  • Dane wyjściowe muszą zostać przycięte do 128 x 96, mimo że algorytm rysuje poza tym obszarem.
  • Jeśli Twój język / platforma nie jest w stanie wydrukować dokładnych kolorów opisanych powyżej, musisz użyć kolorów, które są jak najbardziej zbliżone.
  • Jeśli zdecydujesz się zastosować alternatywną metodę, nadal musisz wygenerować dokładnie ten sam wynik.
  • Na wszelki wypadek: przesłanie oryginalnego kodu asemblera 6502 lub jakiejkolwiek nieznacznie zmodyfikowanej wersji jest niedozwolone.
  • Czy potrafisz pokonać 250 bajtów? Miłego rysowania!

1
„Zachęcanie” jest problematyczne, ponieważ jeśli robi to sprzeczność z oszczędzaniem bajtów, czy ktoś powinien to zrobić, czy nie? Powinno to być albo „musisz” (zrób to, nawet jeśli kosztuje bajtów), albo „możesz” (zrób to tylko, jeśli zaoszczędzi bajty).

1
Zazwyczaj myślę, że lepiej jest podzielić opcję ascii na inne wyzwanie, w przeciwnym razie i tak istnieją 2 pod-wyzwania.
FryAmTheEggman

1
@FryAmTheEggman Pierwotnie miało to być wyłącznie wyjście graficzne, a dodanie tej opcji ASCII było prawdopodobnie złym pomysłem. Mam nadzieję, że nie zrujnuję odpowiedzi WIP, usuwając ją ...
Arnauld

4
@ATaco Paint Starry Nigh było wyzwaniem kodowym mającym inny cel (możliwie jak najwierniejsze odtworzenie obrazu). Jest to zwykła złożoność kolmogorowa o stałej wydajności.
Arnauld

1
To zrozumiałe, Redagowanie mojego bliskiego głosowania.
ATaco

Odpowiedzi:


7

x86 opcode, 227 224 223 bajtów

0000h: 68 20 A8 07 B8 13 00 CD 10 66 BF 40 00 C8 7E 5A
0010h: 89 FD BE 5B 01 AD 89 C7 89 E9 C1 E1 05 66 D1 E7
0020h: 73 09 66 81 F7 B7 1D C1 04 89 FA 80 E2 82 74 09
0030h: 7A 04 78 08 40 40 05 7F 7F 80 C4 02 FE CC 25 7F
0040h: 7F 89 EB 83 E3 03 8A B7 DB 01 88 E3 6B DB 40 01
0050h: C3 26 88 37 E2 C7 4D 75 BC EB FE 0A 03 BE 37 9B
0060h: 2F 2B 07 3C 0E 9B F5 91 8A 0B 1B BD 0E 78 93 3E
0070h: B8 5A B0 B5 70 80 02 B1 D0 D2 9C 93 20 9C 20 11
0080h: 3D D6 26 19 DF F5 97 A3 90 47 A3 F7 8A 59 08 AD
0090h: 29 2C A3 FC 7D 7D 0D 7A D5 51 30 31 D4 2B 54 42
00a0h: B2 14 B1 96 8A 14 29 F1 B0 2C 53 13 04 09 0A BB
00b0h: 3E 16 E9 77 18 E2 B8 72 AC C7 80 40 52 3C 8D AF
00c0h: 3E 63 AD 14 1E 3D B2 8F 23 7B C0 9D AF 2E 31 CE
00d0h: 96 A7 25 37 9E 44 2C B9 2B 39 21 43 00 06 42   

  0100 6820A8                 push A820
  0103 07                     pop es
  0104 B81300                 mov ax, 0013
  0107 CD10                   int 10
  0109 66BF4000C87E           mov edi, 7EC80040
  010F 5A                     pop dx
  0110 89FD                   mov bp, di
  0112 BE5B01                 mov si, 015B
  0115 AD                     lodsw
  0116 89C7                   mov di, ax
  0118 89E9                   mov cx, bp
  011A C1E105                 shl cx, 05
  011D 66D1E7                 shl edi, 01
  0120 7309                   jnb 012B
  0122 6681F7B71DC104         xor edi, 04C11DB7
  0129 89FA                   mov dx, di
  012B 80E282                 and dl, 82
  012E 7409                   je 0139
  0130 7A04                   jpe 0136
  0132 7808                   js 013C
  0134 40                     inc ax
  0135 40                     inc ax
  0136 057F7F                 add ax, 7F7F
  0139 80C402                 add ah, 02
  013C FECC                   dec ah
  013E 257F7F                 and ax, 7F7F
  0141 89EB                   mov bx, bp
  0143 83E303                 and bx, 0003
  0146 8AB7DB01               mov dh, [bx+01DB]
  014A 88E3                   mov bl , ah
  014C 6BDB40                 imul bx, 0040
  014F 01C3                   add bx, ax
  0151 268837                 mov es:[bx], dh
  0154 E2C7                   loop 011D
  0156 4D                     dec bp
  0157 75BC                   jne 0115
  0159 EBFE                   jmp 0159
  015B 0A03BE37...3921        brush_dw
  01DB 43000642               color_db

Obraz: wprowadź opis zdjęcia tutaj


1
Czy miałbyś coś przeciwko dołączeniu wyjaśnienia tego i zrzutu ekranu - ponieważ nie jest to oczywiste
Taylor Scott

Czy powinienem korzystać z aparatu fotograficznego lub środowiska wirtualnego, ponieważ uruchamiam go na pełnym ekranie i nie ma już przechwytywania ekranu
l4m2


1
0122 6681F7B71DC104 xor edi, 00001DB7błąd znaleziony w W32Dasm
l4m2

22

8086 Zestaw - NASM (MBR) - 248 245 bajtów

[org 0x7C00]
[bits 16]
    push 0xA000
    pop es
    mov si, $brush
    xor cx, cx

    mov ax, 0x0013
    int 0x10

    mov ebx, 0x7EC80000

part_loop:
    lodsw
    mov bx, ax

    mov bp, 64
    sub bp, cx
    shl bp, 5
    mov sp, bp

len_loop:
    shl ebx, 1
    jnc not_carry
    xor ebx, 0x04C11DB7
    mov dh, bl
    not_carry:

    and dh, 0x82
    je dir_00
    jpe dir_82
    js dir_80
    dir_02:
        inc al  
        jmp dir_end
    dir_82:
        dec al
        jmp dir_end
    dir_00:
        inc ah
        jmp dir_end 
    dir_80:
        dec ah  
    dir_end:

    and ax, 0x7F7F
    cmp ah, 96
    jae skip

    movzx di, ah
    movzx bp, al
    imul di, 320
    add di, bp
    mov bp, cx
    and bp, 3
    mov dl, byte[bp + color]
    mov [es:di], dl
    skip:

    dec sp
    jnz len_loop
    inc cx
    cmp cx, 64
    jl part_loop    
    jmp $

color:
    db 0x43, 0x42, 0x06, 0x00

brush:
    dw  0x030A, 0x37BE, 0x2F9B, 0x072B, 0x0E3C, 0xF59B, 0x8A91, 0x1B0B
    dw  0x0EBD, 0x9378, 0xB83E, 0xB05A, 0x70B5, 0x0280, 0xD0B1, 0x9CD2
    dw  0x2093, 0x209C, 0x3D11, 0x26D6, 0xDF19, 0x97F5, 0x90A3, 0xA347
    dw  0x8AF7, 0x0859, 0x29AD, 0xA32C, 0x7DFC, 0x0D7D, 0xD57A, 0x3051
    dw  0xD431, 0x542B, 0xB242, 0xB114, 0x8A96, 0x2914, 0xB0F1, 0x532C
    dw  0x0413, 0x0A09, 0x3EBB, 0xE916, 0x1877, 0xB8E2, 0xAC72, 0x80C7
    dw  0x5240, 0x8D3C, 0x3EAF, 0xAD63, 0x1E14, 0xB23D, 0x238F, 0xC07B
    dw  0xAF9D, 0x312E, 0x96CE, 0x25A7, 0x9E37, 0x2C44, 0x2BB9, 0x2139


times 510 - ($-$$) db 0
DB 0x55
DB 0xAA

mona.jpg


6
Och, hej, odpowiedź, która bije wynik w pytaniu (przy założeniu dokładnej liczby bajtów). Miły!
Draco18s,

Witamy w PPCG! wspaniały pierwszy post.
Taylor Scott

Możesz zmniejszyć do 245 bajtów, jeśli usuniesz bezużyteczne xor dx,dxi zmienisz mov bp,0xa000; mov es,bpna push 0xa000; pop es.
Ruslan

1
To nie jest 8086. 8086 nie maPUSH imm
l4m2

1
Podstawowa optymalizacja do 240 paste.ubuntu.com/26272648
l4m2

18

Excel VBA 32-bit, 1011 720 bajtów

Wersja 49; Wynik Δ = 291 bajtów

Grał w golfa

Pełna Subprocedura, która nie pobiera danych wejściowych i wysyła Mona Lisę do ActiveSheetobiektu w zakresie [A1:DX96].

Było dużo czarnej magii zaangażowany w golfa to w dół do jej aktualnego stanu, - nuty, niektóre sztuczki zaangażowane są prep sztuka pikseli , bit przesunięcia kolorów niejawna konwersja typu , a base64kompresja kompresji bajtów jakoString .

Sub M
h Cells,0
t="5¼-™):󙈏"+vbTab+"»‘v¶<®Xn³"+chr(0)+"~ίšÐ‘š;$ÔÝ•óŽ¡¡EˆõW'«¡*{ú{Óx.OÒ/R)°@¯ˆ”'®ïQ*<¹çu¶àªp~ÅP>‹:<­«a°;!¾y­›/,”Ì#¥œ5*B)·7
s=4057*2^19
j=127
For p=0To 63
w=(Asc(Mid(t,2*p+1))+2)*256&+Asc(Mid(t,2*p+2))+2
s=s And-4^8Or w
x=255And w
y=255And w/2^8-.5
For l=1To(64-p)*32
c=s And-2^31
z=2^30And s
s=(1073741823And s)*2
s=IIf(z,s Or-2^31,s)And-1
If c Then:s=79764919Xor s:d=255And s
d=130And d
y=IIf(d,IIf(d=128,y-1And j,y),y+1And j)
x=IIf(d=2,x+1And j,IIf(d=130,x-1And j,x))
h[B2].Cells(y,x),Array(9036543,4562665,23205,0)(3And p)
Next l,p
h[97:999,DY:ZZ],0
End Sub
Sub h(r,c)
r.Interior.Color=c
r.RowHeight=48
End Sub

Uwaga: To rozwiązanie zostało ograniczone do wersji 32-bitowej wersji programu Excel VBA jak ^jest LongLongdosłowna typu w wersji 64-bitowej

Uwaga: Drugi: ciąg znaków w linii 3 nie jest komentarzem, ponieważ nie jest równoważny z"

Wydajność

Gif pokazujący wyjście do ActiveSheetmomentu Mwywołania w bezpośrednim oknie VBE. Zauważ, że z powodu ograniczeń rozmiaru pliku ten rysunek gif ma mniej ramek niż faktycznie wyprodukowano. Mona

Bez golfa

Pełna nieprofesjonalna subprocedura, która nie pobiera danych wejściowych i wytwarza mona lisa przy użyciu metody opisanej powyżej na ActiveSheetobiekcie

Option Private Module
Option Compare Text
Option Explicit
Option Base 0


Public Sub MonaLisa()
    On Error GoTo 0

    Dim part As Integer, _
        length As Integer, _
        M As Long, _
        seed As Long, _
        dir As Long, _
        word As Long, _
        carry As Long, _
        bx As Byte, _
        by As Byte, _
        BRUSH, _
        COLOR

    Let COLOR = Array(&H89E2FF, &H459EE9, &H5AA5, 0)
    Let BRUSH = Array( _
            778, 14270, 12187, 1835, 3644, 62875, 35473, 6923, _
            3773, 37752, 47166, 45146, 28853, 640, 53425, 40146, _
            8339, 8348, 15633, 9942, 57113, 38901, 37027, 41799, _
            35575, 2137, 10669, 41772, 32252, 3453, 54650, 12369, _
            54321, 21547, 45634, 45332, 35478, 10516, 45297, 21292, _
            1043, 2569, 16059, 59670, 6263, 47330, 44146, 32967, _
            21056, 36156, 16047, 44387, 7700, 45629, 9103, 49275, _
            44957, 12590, 38606, 9639, 40503, 11332, 11193, 8505)

    Let dir = 0
    Let carry = 0
    Let seed = &H7EC80000

    Let Cells.Interior.Color = 0
    Let Cells.ColumnWidth = 2

    Call Range("A1:DX96").Select
    Let ActiveWindow.Zoom = True
    Call Range("A1").Select

    For part = 0 To 63 Step 1

        Call VBA.DoEvents

        Let word = BRUSH(part)
        Let seed = (seed And &HFFFF0000) Or word

        Let bx = word And 255
        Let by = Int(word / (2 ^ 8)) And 255

        For length = 0 To (64 - part) * 32 - 1 Step 1

            Let carry = seed And &H80000000
            Let M = seed And &H40000000
            Let seed = (seed And &H3FFFFFFF) * 2
            If M <> 0 Then Let seed = seed Or &H80000000

            Let seed = seed And &HFFFFFFFF

            If carry Then
                Let seed = seed Xor 79764919
                Let dir = Int(seed And 255)
            End If

            Select Case dir And 130
                Case 0:   Let by = Int(by + 1) And 127
                Case 2:   Let bx = Int(bx + 1) And 127
                Case 128: Let by = Int(by - 1) And 127
                Case 130: Let bx = Int(bx - 1) And 127
            End Select
            Let Cells(by + 1, bx + 1).Interior.Color = COLOR(part And 3)
        Next length
    Next part

    Let Range("97:999,DY:ZZ").Interior.Color=0

End Sub

4
Hej, fajna animacja!
Arnauld,

@Arnauld, dzięki: P zajęło więcej pracy niż powinno
Taylor Scott

10

HTML + CSS + JavaScript (ES6), 499 bajtów

  • HTML: 33 bajty
  • CSS: 17 bajtów
  • JS: 678 ... 478 475 473 465 459 455 451 447 449 bajtów

Nigdzie nie jest blisko 250 bajtów, ale na pewno zadowoli mnie mniej niż 500 bajtów! Ogromne podziękowania dla @Arnauld i @Firefly za pomoc w grze w golfa tego potwora.

with(C.getContext`2d`)for(s=4057<<19,d=n=65;n--;)for(w=n-44?` ℹ⮹ⱄ鸷▧雎ㄮ꾝쁻⎏눽Ḕ굣㺯贼剀胇걲룢ᡷ㺻ਉГ匬냱⤔誖넔뉂含퐱け핺ൽ緼ꌬ⦭࡙諷ꍇ那韵�⛖㴑ₜₓ鳒킱ʀ炵끚렾鍸ຽᬋ誑฼ܫ⾛㞾̊`.charCodeAt(n):57113,s=s&~65535|w,x=w&255,y=w>>8,fillStyle="#"+["FFE289","000","A55A00","E99E45"][n&3],k=32*n;k--;fillRect(x,y,1,1))(s*=2)/2>>31&&(d=s^=79764919),D=d&128?-1:1,d&2?x=x+D&127:y=y+D&127
*{background:#000
<canvas id=C width=128 height=96>

Aby uzyskać większą skalę, zamień CSS na:

canvas { background: #000; image-rendering: pixelated; zoom: 3 }

Historia z komentarzami!

Świetnie się bawiłem, grając w kod referencyjny Arnaulda, a niektóre możesz znaleźć tutaj. Cieszyć się!


3
Dobra robota i dzięki za podzielenie się historią!
Arnauld

@Arnauld Glad, aby podjąć wyzwanie!
darrylyeo

9

Befunge, 1131 1052 bajtów

"Dq~"1+00g"Ot"0"-R"0003"7/"727*"E1"5*\2*39*27*"\1"3*\2*:8-"ph"2*2\"N"2*"  =&~a"v
v  *83+"k~>"*524\*2"XS)"*2"E"-1:*2"YT"*2"j0"\+94*3"G}"+"%~)"8*2\+"%~E"-7:+" w"+<
>"V\"2*\2*"@"2*"R/"3*">~/"+56*"Y"2*"##`"2*\5*"1K"2*"%O"2*",+!_"2*25*\"{ "+"+<{"v
v"/~Y"+"y~G"+"%~"*5"1"*55*2"k"+98+9:*3"1"*2\*3";i"*2\+"7~@Z>x"*3"?"+92+" q"+" "<
>+",~"2*"}zQ1+BK"2*45*\45*",~s"+\25*9+9"~="+29+2*"wq"2*"r~I"+"@<c#"5*\45*"=o "+v
  v_,#!>#:<"P3 128 96 127"_v`+" k":p39+1:%*:*82<<0<<<\*5"%9D7"+")~"*2"g."+" }{"<
#@_:63p"@d~"03p2*13p043p0v^_:"@"%\"@"/p93g28*:*+^>\04>1-:93p3g2*+:v>g+\%:v>:"_"`
_3*55+,:2g.:1+2g.2+2g.1+v_:48**\1-:83p\83g:1g:23p\0v |:g39`\0p3g39<3v4\+4<^+1$$<
`v0:\%4g++77/"@"\%"@":::<^!:$$_\73g>0#p0#33g#:`#g^#< _$!#v_28*:*::0^>/2%8*-03p:v
">\:88vv%"@":\g38:\<_\73p\1-:!^v4:%\+g32::p31-*2+%2\*"@"% 4/"@":\++"C~":%\+g31:<
~v<\%*<>\"@"/77++p\0^!-g36:%**<>5*9++\:4/8%4*\2%+2*-23p:3 3g+\%:"="3*+\033g`28*v
">88*/7v>g!+53g2-!-153g2%+28*8^v2`\0\%2/2+*:*82:g34+*:*82<p34p33:-*2++%8\*+88< 8
^-1p++7<^35+*:*28\%**8*28-%2g35>#<*#2+#-:#!5#-3#3p#g1#3-#5!#+< >8+#:/#\4#*%#*^#<

Istnieje wiele problemów, które sprawiają, że jest to trudny problem w Befunge:

  1. Befunge ma tylko 2000 bajtów pamięci do pracy (wraz z kodem źródłowym), więc nie ma możliwości, abyśmy mogli wyrenderować cały obraz w pamięci przed wysłaniem go. Sposób obejścia tego problemu polega na wielokrotnym uruchamianiu algorytmu 96 razy, raz dla każdej linii. Każdy przebieg przechowuje tylko piksele potrzebne w bieżącej linii, które są następnie wyprowadzane na końcu przebiegu. To pozwala nam poradzić sobie z buforem pikseli o wielkości zaledwie 128 bajtów.

  2. Befunge nie ma żadnych operacji. Wiele ANDoperacji można po prostu emulować za pomocą operatora modulo (np. a AND 0x7FMożna je zastąpić a % 0x80). Jednak XORwymaga dość skomplikowane manipulacje bitów, co mamy do czynienia z jednym bajcie na raz, przy użyciu zestawu niestandardowych wzorów Hardcoded obsłużyć cztery bajty, których potrzebujemy. Na przykład do obliczenia a XOR 0xC1używamy wzoru:a + 0xC1 - (a/64%4*64 + a%2)*2

  3. Interfejs TIO nie jest ograniczeniem percepcji jako takiej, ale nie jest w stanie obsługiwać rozszerzonych znaków ASCII w źródle, co byłoby najłatwiejszym sposobem przechowywania tabel pędzla i kolorów. Pracuję nad tym, generując te tabele jako listę liczb na stosie, a następnie mam małą pętlę inicjującą, która kopiuje wartości ze stosu do pamięci. Znaczną część mojego czasu spędziłem na grze w golfa przy tym stole, który zajmuje pierwsze pięć i pół linijki kodu.

Niestety, pomimo wszystkich moich starań, aby kod był zgodny z TIO i wybrałem format pliku, który można wyodrębnić z TIO ( PPM ), jest on zbyt wolny, aby wypełnić go w 60-sekundowym limicie czasu (prawdopodobnie algorytm jest uruchamiany 96 razy nie pomaga). Ale ponieważ generuje obraz linia po linii, powinieneś uzyskać wystarczającą ilość danych wyjściowych, aby odzyskać prawie połowę obrazu.

Wypróbuj online!

Jeśli nie masz lokalnej przeglądarki plików PPM, możesz łatwo przekonwertować ją na inny format za pomocą jednego z wielu konwerterów online. Jednym z przykładów jest Convertio .


Prawdopodobnie nie jest to najłatwiejsze narzędzie do pracy. Dobra robota!
Arnauld,

7

Python 3, 544 536 523 519 518 bajtów

from tkinter import*
s=32456<<16
d=0
b="#000"
a=Canvas(Tk(),w=128,he=96,bg=b)
a.pack()
for p in range(64):w=ord("̊㞾⾛ܫ฼誑ᬋຽ鍸렾끚炵ʀ킱鳒ₓₜ㴑⛖\udf19韵那ꍇ諷࡙⦭ꌬ緼ൽ핺け퐱含뉂넔誖⤔냱匬Гਉ㺻ᡷ룢걲胇剀贼㺯굣Ḕ눽⎏쁻꾝ㄮ雎▧鸷ⱄ⮹ℹ"[p]);s=s&~65535|w;*e,=divmod(w,256)[::-1];exec("c=s&8<<28>0;s=s*2^79764919*c;d=[d,s&255][c];e[d&2<1]=e[d&2<1]+(d&128<1)*2-1&127;a.create_line(*e,e[0]+1,e[1]+1,f=['#FFE289','#E99E45','#A55A00',b][p&3]);"*(64-p)*32)

Jest to kolejna nieudolna wersja implementacji referencyjnej CCB60 w języku Python. Początkowo użyłem dużej liczby szesnastkowej do przedstawienia pędzla algorytmu, ale później zdałem sobie sprawę, że moje nieuzasadnione założenie, że reprezentacja ciągu Unicode nie zadziała w Pythonie, było fałszywe.

Początkowo myślałem, że moja liczba bajtów jest znacznie niższa, ale jak zauważyłem tylko ASCII , nie pamiętam, aby liczyć znaki Unicode jako więcej niż jeden bajt.

Wyjście (128 x 96)

Mona Lisa w oknie tk

Identyczny z wyjściem CCB60.


Jest to 518 bajtów, a nie 396
tylko ASCII,

@ Tylko ASCII Zapomniałem policzyć znaki Unicode jako więcej niż jeden bajt. Nie. Nic dziwnego, że liczba bajtów wydawała się tak niska ...
notjagan

7

Java 7, 681 677 675 626 612 610 bajtów

Object l(){BufferedImage g=new BufferedImage(128,96,1);String b="̊㞾⾛
ܫ\u0E3C\uF59B誑ᬋຽ鍸렾끚炵ʀ킱鳒ₓₜ㴑⛖\udf19韵那ꍇ諷࡙⦭ꌬ緼ൽ핺け퐱含뉂넔誖⤔냱匬Гਉ
\uE916ᡷ룢걲胇剀贼㺯굣Ḕ눽⎏쁻꾝\u312E雎▧鸷ⱄ\u2BB9";for(int 
s=0x7EC80000,d=0,x,y,z=130,u,w,c,r=255,t=127,p=0,o;p<64;p++)
{w=b.charAt(p);s=s&0xFFFF0000|w;x=w&r;y=(w>>8)&r;for(o=0;o<(64-p)*32;o++)
{c=s&0x80000000;s<<=1;if(c!=0){s^=0x4C11DB7;d=s&r;}x=(u=d&z)==2?x+1&t:u==z?
x-1&t:x;y=u==0?y+1&t:u==128?y-1&t:y;if(x<128&y<96)g.setRGB(x,y,new int[]
{0xFFE289,0xE99E45,0xA55A00,0}[p&3]);}}return g;}

Wysyła następujący obraz w rozdzielczości 128x96:
wprowadź opis zdjęcia tutaj

Wiem, że nie ma nawet 250 bajtów, ale hej, to java

-2 bajty dzięki Zacharýowi


Hej, wygląda na to, że nikt nie przywitał cię w PPCG, więc cześć i witaj w PPCG! Ładny pocztowy, mam tylko dwa zalecenia formatowania dla Ciebie 1, nagłówek jest, ze względu na mające liderów ma być formatu #Language, <s>Old Scores</s> Score Bytesi 2 można dokonać kod nieco bardziej czytelne, dodając w fladze językowej formie <!-- language-all: lang-java -->przed twój blok kodu
Taylor Scott,

1
Hej, dziękuję za przyjęcie mnie :)! Zredagowałem teraz mój post z proponowanymi ulepszeniami.
Twometr

2
Nie ma problemu @ Twometr, wygląda świetnie i mam nadzieję, że spodoba ci się gra w golfa
Taylor Scott,

1
Można ogolić dwa bajty: 0x04C11DB7=> 0x4C11DB7i 0x7f=> 127. Nie zwariuj, gdy nie jest to potrzebne.
Zacharý

1
Uwielbiam to „ale hej, to Java”
Jack

4

C #, 960 850 bajtów

using System.Drawing;_=>{var m = new Bitmap(128,96);Graphics.FromImage(m).FillRectangle(Brushes.Black,0,0,128,96);for(int s=0x7EC80000,d=0,p=0,w,x,y,l,c,t,n=127;p<64;++p){w=new[]{778,14270,12187,1835,3644,62875,35473,6923,3773,37752,47166,45146,28853,640,53425,40146,8339,8348,15633,9942,57113,38901,37027,41799,35575,2137,10669,41772,32252,3453,54650,12369,54321,21547,45634,45332,35478,10516,45297,21292,1043,2569,16059,59670,6263,47330,44146,32967,21056,36156,16047,44387,7700,45629,9103,49275,44957,12590,38606,9639,40503,11332,11193,8505}[p];s=s>>16<<16|w;x=w&255;y=w>>8&255;for(l=0;l++<(64-p)*32;){c=(int)(s&0x80000000);s*=2;if(c!=0){s^=79764919;d=s&255;}t=d&130;x=t==2?(x+1)&n:t==130?(x-1)&n:x;y=t<1?(y+1)&n:t==128?(y-1)&n:y;if(x<=n&y<96)m.SetPixel(x,y,Color.FromArgb((int)new[]{0xFFFFE289,0xFFE99E45,0xFFA55A00,0xFF000000}[p&3]));}}return m;}

Prosta kopia pseudo kodu z dodanym golfem. Wciąż jest wiele rzeczy do gry w golfa, ale chciałem opublikować swoją odpowiedź, aby piłka się potoczyła.

Wersja pełna / sformatowana:

using System.Drawing;

class P
{
    static void Main()
    {
        System.Func<object, Bitmap> f = _ =>
        {
            var m = new Bitmap(128, 96);
            Graphics.FromImage(m).FillRectangle(Brushes.Black, 0, 0, 128, 96);

            for (int s = 0x7EC80000, d = 0, p = 0, w, x, y, l, c, t, n = 127; p < 64; ++p)
            {
                w = new[] { 778, 14270, 12187, 1835, 3644, 62875, 35473, 6923, 3773, 37752, 47166, 45146, 28853, 640, 53425, 40146, 8339, 8348, 15633, 9942, 57113, 38901, 37027, 41799, 35575, 2137, 10669, 41772, 32252, 3453, 54650, 12369, 54321, 21547, 45634, 45332, 35478, 10516, 45297, 21292, 1043, 2569, 16059, 59670, 6263, 47330, 44146, 32967, 21056, 36156, 16047, 44387, 7700, 45629, 9103, 49275, 44957, 12590, 38606, 9639, 40503, 11332, 11193, 8505 }[p];
                s = s >> 16 << 16 | w;
                x = w & 255;
                y = w >> 8 & 255;

                for (l = 0; l++ < (64 - p) * 32;)
                {
                    c = (int)(s & 0x80000000);
                    s *= 2;

                    if (c != 0)
                    {
                        s ^= 79764919;
                        d = s & 255;
                    }

                    t = d & 130;

                    x = t == 2 ? (x + 1) & n : t == 130 ? (x - 1) & n : x;
                    y = t < 1 ? (y + 1) & n : t == 128 ? (y - 1) & n : y;

                    if (x <= n & y < 96)
                        m.SetPixel(x, y, Color.FromArgb((int)new[] { 0xFFFFE289, 0xFFE99E45, 0xFFA55A00, 0xFF000000 }[p & 3]));
                }
            }

            return m;
        };

        f(null).Save("monaLisa.jpg");
    }
}

1
var m = new Bitmap(128,96)AE IU WAUGH WY
CalculatorFeline

2
@CalculatorFeline Nie rozumiem?
TheLethalCoder,

8
Możliwe z powodu niepotrzebnych miejsc?
Zacharý

3

Python 2.7; 880 876 bajtów łącznie (łącznie z danymi)

-4 bajty do 876 dzięki ZacharyT. (Mój interpreter pytona nie podobał się jego sugestii, by upuścić spacje między latami 80. i jeszcze innymi).

Sugestia Taylora Scotta, aby umieścić pędzel w bazie 10, jest doskonała, ale notjagan (w komentarzu) posunął swoją sugestię o krok dalej, używając rozszerzonego formatu liczb całkowitych Pythona w zapisie szesnastkowym. odpowiedź notjagana znajduje się w Pythonie 3 i jest to taka poprawa w stosunku do tego, co zrobiłem, że zasługuje na uznanie. Mam nadzieję, że opublikuje to jako osobną odpowiedź.

Wyjście do okna Tkinter. Bez skalowania obraz jest bardzo mały, ale skalowanie dodaje około kilkunastu bajtów.

B=[0x030A,0x37BE,0x2F9B,0x072B,0x0E3C,0xF59B,0x8A91,0x1B0B,
0x0EBD,0x9378,0xB83E,0xB05A,0x70B5,0x0280,0xD0B1,0x9CD2,
0x2093,0x209C,0x3D11,0x26D6,0xDF19,0x97F5,0x90A3,0xA347,
0x8AF7,0x0859,0x29AD,0xA32C,0x7DFC,0x0D7D,0xD57A,0x3051,
0xD431,0x542B,0xB242,0xB114,0x8A96,0x2914,0xB0F1,0x532C,
0x0413,0x0A09,0x3EBB,0xE916,0x1877,0xB8E2,0xAC72,0x80C7,
0x5240,0x8D3C,0x3EAF,0xAD63,0x1E14,0xB23D,0x238F,0xC07B,
0xAF9D,0x312E,0x96CE,0x25A7,0x9E37,0x2C44,0x2BB9,0x2139]
s=0x7EC80000
d=0x00
from Tkinter import *
m=Tk()
a=Canvas(m,w=128,he=96,bg='black')
a.pack()
for p in range(64):
 w=B[p];s=(s&0xFFFF0000)|w;x=w%256;y=w/256
 for t in range((64-p)*32):
  c=s&0x80000000;s=(s<<1)&0xFFFFFFFF;
  if c:s=s^0x04C11DB7;d=s&0xFF
  if d&2:x=(x+(-1if d&0x80 else 1))&0x7f
  else:y=(y+(-1if d&0x80 else 1))&0x7f
  a.create_line(x,y,x+1,y+1,f=['#FFE289','#E99E45','#A55A00','#000000'][p&3])
mainloop()

Niewiele się tu dzieje poza tłumaczeniem na Python i podstawową grą w golfa. Czasami manipulacje bitowe są krótsze, czasem matematyka całkowita. Nie mogłem znaleźć sposobu na spakowanie większej ilości logiki do list lub tablic. Podstawowy algorytm jest już dość gęsty.

Mona Lisa jako wyjście Tkintera


1
Tylko wskazówka dotycząca formatowania, możesz uczynić kod nieco bardziej czytelnym, dodając wyróżnianie specyficzne dla języka za pomocą prettify.js. Dla Pythona ta flaga, którą należy dodać przed zakodowaniem bloku (bloków), wygląda następująco<!-- language-all: lang-py -->
Taylor Scott

2
Nie potrzebujesz odstępu między 80„a else”. I czy 0x00to to samo 0, prawda?
Zacharý

2
I możesz usunąć przestrzeń między importi *.
Zacharý

1
Zmniejszono go do 641 bajtów , przechodząc na Python 3 i wprowadzając ogólne ulepszenia w golfa.
notjagan

1

2

Tcl / Tk, 805

808 815 816 819 826 839 840 843

Mona

Wciąż przegrany, ale musiałem to zrobić! być może mogę później zagrać w golfa!

Teraz nie przegrany!

rename set S
rename expr E
pack [canvas .c -w 130 -he 98 -bg #000]
.c cr i 67 51 -i [S I [image c photo -w 128 -h 96]]
S s 0x7EC80000
S d 0
time {S s [E $s&0xFFFF0000|[S w 0x[lindex {. 30A 37BE 2F9B 72B E3C F59B 8A91 1B0B
EBD 9378 B83E B05A 70B5 280 D0B1 9CD2
2093 209C 3D11 26D6 DF19 97F5 90A3 A347
8AF7 859 29AD A32C 7DFC D7D D57A 3051
D431 542B B242 B114 8A96 2914 B0F1 532C
413 A09 3EBB E916 1877 B8E2 AC72 80C7
5240 8D3C 3EAF AD63 1E14 B23D 238F C07B
AF9D 312E 96CE 25A7 9E37 2C44 2BB9 2139} [incr p]]]]
S x [E $w&255]
S y [E $w>>8]
time {S c [E $s&1<<31]
S s [E $s<<1]
if \$c {S s [E $s^79764919]
S d [E $s&255]}
switch [E $d&130] {0 {S y [E $y+[S h 1&127]]}
2 {S x [E $x+$h]}
128 {S y [E $y-$h]}
130 {S x [E $x-$h]}}
$I p #[lindex {FFE289 E99E45 A55A00 000} [E $p-1&3]] -t $x $y} [E (65-$p)*32]} 64

Tcl / Tk, 1370

Bardzo nieokreślona transliteracja pseudokodu przed rozpoczęciem szału golfowego! updateLinia sprawia, że możliwe, aby zobaczyć rysunek robione stopniowo!

pack [canvas .c -w 130 -he 98 -bg #000]
.c create i 67 51 -i [set p [image create photo -w 128 -h 96]]

set COLOR {FFE289 E99E45 A55A00 000000}

set BRUSH {
 0x030A 0x37BE 0x2F9B 0x072B 0x0E3C 0xF59B 0x8A91 0x1B0B 
 0x0EBD 0x9378 0xB83E 0xB05A 0x70B5 0x0280 0xD0B1 0x9CD2 
 0x2093 0x209C 0x3D11 0x26D6 0xDF19 0x97F5 0x90A3 0xA347 
 0x8AF7 0x0859 0x29AD 0xA32C 0x7DFC 0x0D7D 0xD57A 0x3051 
 0xD431 0x542B 0xB242 0xB114 0x8A96 0x2914 0xB0F1 0x532C 
 0x0413 0x0A09 0x3EBB 0xE916 0x1877 0xB8E2 0xAC72 0x80C7 
 0x5240 0x8D3C 0x3EAF 0xAD63 0x1E14 0xB23D 0x238F 0xC07B 
 0xAF9D 0x312E 0x96CE 0x25A7 0x9E37 0x2C44 0x2BB9 0x2139}

set seed 0x7EC80000
set dir 0x00

set part 0
while {$part<64} {
  set word [lindex $BRUSH $part]
  set seed [expr ($seed&0xFFFF0000)|$word]
  set bx [expr $word&0xFF]
  set by [expr $word>>8]

  set len 0
  while {$len<[expr (64-$part)*32]} {
    set carry [expr $seed&0x80000000]
    set seed [expr $seed<<1]

    if \$carry {
      set seed [expr $seed^0x04C11DB7]
      set dir [expr $seed&0xFF]
    }

    switch [expr $dir&0x82] {
      0 {
        set by [expr $by+1&0x7F]
      }
      2 {
        set bx [expr $bx+1&0x7F]
      }
      128 {
        set by [expr $by-1&0x7F]
      }
      130 {
        set bx [expr $bx-1&0x7F]
      }
    }

    $p put #[lindex $COLOR [expr $part&3]] -to $bx $by
    incr len
    update
  }
  incr part
}

2

Python 3 + matplotlib, 541

from pylab import*
B='ਃ븷鬯⬇㰎鯵醊ଛ봎碓㺸媰땰耂뇐튜錠鰠ᄽ혦᧟ꎐ䞣夈괩ⲣﱽ納竕儰㇔⭔䊲ᒱ隊ᐩⱓጄऊ묾ᛩ眘犬잀䁒㲍꼾掭ᐞ㶲輣節鶯⸱캖ꜥ㞞䐬뤫㤡'
s=32456<<16
d=0
i=zeros((256,256),'I')
for p in range(64):
    W=ord(B[p]);w=W>>8|W%256<<8;s=s&65535<<16|w;x=[w>>8,w&255]
    for l in range((64-p)*32):
        s*=2
        if s>>32:s=d=s^4374732215
        a=(-1)**(d>>7);b=d>>1&1;x[b]=x[b]+a&127;i[(*x,)]=[9036543,4562665,23205,0][p&3]
imsave('i',i.view('4B')[:96,:128,:3])

To zapisuje obraz jako plik png „i”. Aby wyświetlić obraz, możesz zastąpić imsave imshow i show na 545 bajtów.

wprowadź opis zdjęcia tutaj


2

SmileBASIC, 454 447 444 bajtów

DIM C[5]C[1]=-7543C[2]=-1466811C[3]=-5940736S=32456<<16FOR P=-63TO.W=ASC("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"[-P])S=W+(S>>16<<16)C[4]=127AND W
C[0]=W>>8FOR L=0TO 31-P*32O=S
S=S<<1IF O<0THEN S=79764919XOR S:D=130AND S
T=D*2AND 4C[T]=127AND C[T]-(D>>6)+1GPSET C[4],C[0]+144,C[3AND P]NEXT
NEXT

Ciąg „x” zawierał nieprawidłowe znaki Unicode, więc nie mogę go tutaj opublikować. Oto kody znaków w postaci dziesiętnej (tylko tablica BRUSH w odwrotnej kolejności):8505, 11193, 11332, 40503, 9639, 38606, 12590, 44957, 49275, 9103, 45629, 7700, 44387, 16047, 36156, 21056, 32967, 44146, 47330, 6263, 59670, 16059, 2569, 1043, 21292, 45297, 10516, 35478, 45332, 45634, 21547, 54321, 12369, 54650, 3453, 32252, 41772, 10669, 2137, 35575, 41799, 37027, 38901, 57113, 9942, 15633, 8348, 8339, 40146, 53425, 640, 28853, 45146, 47166, 37752, 3773, 6923, 35473, 62875, 3644, 1835, 12187, 14270, 778

wprowadź opis zdjęcia tutaj


Umieściłeś obraz wyjścia, czy można opublikować obraz zawartości "xx...xx"ciągu?
Taylor Scott

1
Większość znaków w rzeczywistości nie ma zdefiniowanych symboli, więc tak naprawdę wygląda to jak „xxxxxxxxxxx”. Mogę jednak uzyskać listę kodów znaków.
maja

To może być pomocne - myślę, że mogę użyć podobnej metody z yabasic - och, już to zrobiłeś - coolio
Taylor Scott

Nie zajmuje dużo miejsca, ponieważ (przynajmniej w UTF-8) większość z nich jest zapisywana jako 3 lub więcej bajtów. Ale wciąż jest lepszy niż hex i możesz być w stanie skrócić dekoder.
maja21

1

: r4, 764 bajtów

źródło do uruchomienia w : r4 github

wprowadź opis zdjęcia tutaj

^r4/lib/gui.txt
#c $FFE289 $E99E45 $A55A00 $000000
#b $37BE030A $072B2F9B $F59B0E3C $1B0B8A91 $93780EBD $B05AB83E $028070B5 $9CD2D0B1 $209C2093 $26D63D11 $97F5DF19 $A34790A3 $08598AF7 $A32C29AD $0D7D7DFC $3051D57A $542BD431 $B114B242 $29148A96 $532CB0F1 $0A090413 $E9163EBB $B8E21877 $80C7AC72 $8D3C5240 $AD633EAF $B23D1E14 $C07B238F $312EAF9D $25A796CE $2C449E37 $21392BB9
:m pick2 + $7f7f and dup $7f and over 8 >> 96 >? ( 2drop ; ) setxy ink@ a! ;
:s +? ( 2* ; ) 2* $4c11db7 xor rot drop dup 24 << 31 >> 1 or over $2 and 2 << 8 xor << rot rot ;
:d $100 $7ec80000 0 ( 64 <? )( dup $3 and 2 << 'c + @ ink dup >r 2* 'b + w@ $ffff and swap $ffff0000 and over or 64 r@ - 5 << ( 1? )( >r s swap m swap r> 1- ) drop nip r> 1+ ) 3drop ;
: cls d show 'exit >esc< ;

Używam sztuczki do wykonania ruchu bez warunków, przekształcam bit 8 na znak i przesuwam z bitem 2. wersja z nazwami stosu:

| PHREDA 2017
| https://codegolf.stackexchange.com/questions/126738/lets-draw-mona-lisa
^r4/lib/gui.txt

#color  $FFE289 $E99E45 $A55A00 $000000
#brush [
$030A $37BE $2F9B $072B $0E3C $F59B $8A91 $1B0B
$0EBD $9378 $B83E $B05A $70B5 $0280 $D0B1 $9CD2
$2093 $209C $3D11 $26D6 $DF19 $97F5 $90A3 $A347
$8AF7 $0859 $29AD $A32C $7DFC $0D7D $D57A $3051
$D431 $542B $B242 $B114 $8A96 $2914 $B0F1 $532C
$0413 $0A09 $3EBB $E916 $1877 $B8E2 $AC72 $80C7
$5240 $8D3C $3EAF $AD63 $1E14 $B23D $238F $C07B
$AF9D $312E $96CE $25A7 $9E37 $2C44 $2BB9 $2139 ]

:movxy | dir seed bxy -- dir seed bxy 
  pick2 + $7f7f and
  dup $7f and
  over 8 >>
  96 >? ( 2drop ; )
  setxy ink@ a! ;

:step | dir bxy seed -- dir bxy seed
  +? ( 2* ; )
  2* $4c11db7 xor
  rot drop
  dup 24 << 31 >> 1 or
  over $2 and 2 << 8 xor <<
  rot rot ;

:draw
  $100      | dir
  $7ec80000 | seed
  0 ( 64 <? )(
    dup $3 and 2 << 'color + @ ink
    dup >r 2* 'brush + w@ $ffff and | dir seed brush
    swap $ffff0000 and over or      | dir bxy seed
    64 r@ - 5 << ( 1? )( >r         | dir bxy seed
        step swap movxy swap r> 1- ) drop nip
    r> 1+ ) 3drop ;

: cls draw show 'exit >esc< ;

1

Yabasic, 790 779 bajtów

odpowiedź, że nie bierze wejścia i wyjścia w nowym oknie graficznym.

Open Window 128,96
j=127
s=4057*2^19
k=255
For p=-1To 63
Color Mid$("255,226,137233,158,069165,090,0000,0,0",1+And(3,p)*11,11)
If p<0Then Fill Circle 0,0,k:p=0Fi
w=Dec(Mid$("30A37BE2F9B072B0E3CF59B8A911B0B0EBD9378B83EB05A70B50280D0B19CD22093209C3D1126D6DF1997F590A3A3478AF7085929ADA32C7DFC0D7DD57A3051D431542BB242B1148A962914B0F1532C04130A093EBBE9161877B8E2AC7280C752408D3C3EAFAD631E14B23D238FC07BAF9D312E96CE25A79E372C442BB92139",4*p,4),16)
s=Or(And(-4^8,s),w)
x=And(k,w)
y=And(w/2^8,k)
For l=1To(64-p)*32
c=And(-2^31,s)
z=And(2^30,s)
s=And(1073741823,s)*2
t=s
If z Then t=Or(s,-2^31)Fi
s=And(-1,t)
If c Then s=Xor(79764919,s):d=And(k,s)Fi
d=And(130,d)
If d=0Then y=And(y+1,j)Fi
If d=2Then x=And(x+1,j)Fi
If d=128Then y=And(y-1,j)Fi
If d=130Then x=And(x-1,j)Fi
Dot x,y
Next
Next

Wydajność

Poniżej skaluje się współczynnik 8

Mona.yab

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.