Programowanie wykładniczo śluzowate: układanie szlamów Minecraft


108

Szlam to wrogowie w kształcie kostki w Minecraft , którzy po zabiciu dzielą się na wiele mniejszych wersji. Na potrzeby tego wyzwania przedstawimy je jako obraz 8 × 8 pikseli w 3 kolorach:

Szlam 64x64

Szlam 8x8 ← Prawdziwa wersja 8 × 8.

Dokładne kolory RGB to:

  • 0, 0, 0 dla oczu i ust
  • 110, 170, 90 dla środkowej, ciemniejszej zieleni
  • 116, 196, 96 dla zewnętrznej, jaśniejszej zieleni

Wyzwanie

Napisz program lub funkcję, która przyjmuje dodatnią liczbę całkowitą N i wyświetla obraz N rozmiarów szlamów upakowanych w prostokąt. Przechodząc od lewej do prawej, obraz powinien być zgodny z następującym wzorem:

  • Stos 2 (N-1) 8 × 8 szlamów.
  • Stos 2 (N-2) 16 × 16 szlamów.
  • Stos 2 (N-3) szlamów 32 × 32.
  • I tak dalej, aż stos zawiera tylko jeden szlam.

Obrazy szlamu większe niż wersja 8 × 8 ( Szlam 8x8) są generowane przez upsampling najbliższego sąsiada (tj. Po prostu podwojenie wszystkich pikseli). Pamiętaj, że musisz użyć dokładnego projektu szlamu i kolorów podanych tutaj.

Końcowy obraz będzie zawierał 2 N- 1 szlam i będzie miał 2 (N + 3) -8 pikseli szerokości i 2 (N + 2) pikseli wysokości.

Obraz może być wyprowadzany w dowolnym popularnym formacie pliku obrazu, zapisany w pliku lub wydrukowany / zwrócony jako nieprzetworzony strumień danych, lub bezpośrednio wyświetlony podczas działania.

Najkrótszy kod w bajtach wygrywa.

Przykłady

Twój program powinien dać te dokładne wyniki.

N = 1:

N = 1

N = 2:

N = 2

N = 3:

N = 3

N = 4:

N = 4

N = 5:

N = 5

N = 6:

N = 6

Większy N powinien równie dobrze działać.


30
Chciałbym głosować, ale nie mam już głosów. Zostawiam ten komentarz, więc będę pamiętać, aby jutro głosować.
NoOneIsHere

23
Głosuję za waszym komentarzem, ponieważ zabrakło mi też głosów pozytywnych.
trichoplax

4
„Obrazy szlamu większe niż wersja 8 × 8 () są generowane przez upsampling najbliższego sąsiada (tj. Po prostu podwojenie wszystkich pikseli).” Miałeś na myśli czterokrotność wszystkich pikseli, uczynienie każdego piksela kwadratem 2x2?
Caridorc,

1
@Caridorc Podwajanie w każdym kierunku?
wizzwizz4,

@ wizzwizz4 Tak, każdy piksel staje się 4, prawda?
Caridorc,

Odpowiedzi:


21

MATL , 77 76 74 bajtów

:"')^.,9&Xze`}+.E=p'F3ZaQ8e@qWt3$Y"G@-W1X"]&h[OOO;11 17E]5*29 7U24hhE&vEYG

Kod działa w tym zatwierdzeniu , które jest wcześniejsze niż wyzwanie.

Możesz spróbować w MATL online . Ten tłumacz jest wciąż eksperymentalny. Jeśli to nie działa, spróbuj odświeżyć stronę i ponownie nacisnąć „Uruchom”.

Oto przykład uruchamiany w tłumaczu offline:

wprowadź opis zdjęcia tutaj

Wyjaśnienie

:                     % Input N implicitly. Generate range [1 2 ... N]
"                     % For each k in [1 2 ... N]
  ')^.,9&Xze`}+.E=p'  %   Compressed string
  F3Za                %   Decompress with target alphabet [0 1 2]
  Q                   %   Add 1
  8e                  %   Reshape into 8×8 array containing values 1, 2, 3
  @qW                 %   Push 2 raised to k-1
  t                   %   Duplicate
  3$Y"                %   Repelem: interpolate image by factor 2 raised to k-1
  G@-W                %   Push 2 raised to N-k
  1X"                 %   Repmat: repeat the array vertically. Gives a vertical strip
                      %   of repeated subimages
]                     % End for each
&h                    % Concatenate all vertical strips horizontally. This gives a big
                      % 2D array containing 1, 2, 3, which represent the three colors
[OOO;11 17E]5*        % Push array [0 0 0; 11 17 9] and multiply by 5
29 7U24hhE            % Push array [29 49 24] and multiply by 2
&vE                   % Concatenate the two arrays vertically and multiply by 2.
                      % This gives the colormap [0 0 0; 110 170 90; 116 196 96]
YG                    % Take the array and the colormap and display as an image

„Większy N powinien równie dobrze działać.”, Ale wydaje się, że już w n = 9 wydaje się występować błąd braku pamięci / indeksu. Czy to tylko interpreter online, czy też dzieje się tak również w wersji offline?
David Mulder,

1
@DavidMulder Przetestowałem offline (kompilator działający na Matlab R2015b, Windows 7 64 bity, 4 GB pamięci RAM) dla danych wejściowych do 11i działa. W 11rezultacie powstaje obraz 8192 × 16376. Na 12byłoby 16384 x 32760 (536 megapikseli), co wymaga ciągu 4 GB pamięci RAM, który jest więcej niż my laptop może obsłużyć.
Luis Mendo,

2
Podoba mi się, jak kod zaczyna się od buźki, która powstrzymuje łzy z powodu intensywnych emocji, które wywołuje w nim ten kod: „”)
Tom Doodler

14

Dyalog APL, 118 113 bajtów

('P3',⌽∘⍴,255,∊)(3↑(116 196 96)(110 170 90))[⊃,/i{⊃⍪/⍵⍴⊂⍺⌿⍺/8 8⍴∊22923813097005 926134669613412⊤¨⍨⊂32⍴3}¨⌽i←2*⍳⎕]

zarozumiały ⎕IO=0

Z prawej do lewej:

i←2*⍳⎕ uprawnienia 1 2 4 ... 2 n-1

i{ }¨⌽iiteruj po potęgach (z ) i potęgach odwróconych ( )

⊤¨⍨⊂32⍴3 dekodować każdą liczbę po lewej jako 32 cyfry trójskładnikowe

8 8⍴∊ spłaszcz i przekształć do formatu 8 × 8

⍺⌿⍺/powtórz czasy w każdym wierszu i kolumnie

⍵⍴⊂robić kopie

⊃⍪/ i układaj je pionowo

⊃,/ połącz wszystkie wyniki poziomo

3↑(116 196 96)(110 170 90)zabarwienie; 3↑rozszerza je o(0 0 0)

[ ]indeksuj kolory dla każdego elementu matrycy; wynikiem jest macierz RGB

('P3',⌽∘⍴,255,∊)to „pociąg” - funkcja, która powraca, 'P3'po której następuje odwrócony kształt argumentu 255, a argument zostaje spłaszczony.


Myślę, że możesz napisać swój program, zakładając, ⎕IO←0że jest to warunek poza liczbą bajtów. Wiele systemów APL używa tego domyślnie. (W tym twój LOL)
Tobia,

11

JavaScript (ES7), 326 327 bajtów

n=>{x=(d=document).body.appendChild(c=d.createElement`canvas`).getContext`2d`;c.width=2*(c.height=4*(p=2**n)));for(i=0;i<n;i++){c=-1;for(j of[...'0001000001111110022112200221122011111110011121110111111000010000'])for(x.fillStyle=['#74c460','#6eaa5a','#000'][j],c++,k=0;k<p;)x.fillRect(c%8*(_=2**i)+_*8,~~(c/8)*_+_*8*k++,_,_)}}

Wersja Ungolfed ES6

Spróbuj sam.

(n=>{
    x=(d=document).body.appendChild(c=d.createElement`canvas`).getContext`2d`;
    c.width=2*(c.height=4*(p=Math.pow(2,n)));
    for(i=0;i<n;i++){
        c=-1;
        for(j of[...'0001000001111110022112200221122011111110011121110111111000010000'])
            for(x.fillStyle=['#74c460','#6eaa5a','#000'][j],c++,k=0;k<p;)
                x.fillRect(c%8*(_=Math.pow(2,i))+_*8,~~(c/8)*_+_*8*k++,_,_)
    }
})(4);

Jedyną różnicą między wersją ES7 i ES6 jest użycie **zamiast Math.pow(). Możesz także zobaczyć, jak wywołać funkcję - w tym przykładzie za pomocą n=4.

Wynik

wprowadź opis zdjęcia tutaj


Edycje

  • zapisano 1 bajt - znaleziono niepotrzebny końcowy średnik;

Jest to dość powolne i może zająć trochę czasu dla liczb większych niż 10.


2
kolory wydają się nieco nie na zdjęciu tutaj. Czy może zrzut ekranu z włączonym f.lux?
Jezzamon

@Jezzamon Dzięki za zwrócenie na to uwagi - też to zauważyłem. Istnieje niewielka możliwość , że może wybrało „ Konwersja kolorów dokumentu do przestrzeni roboczej ” podczas importowania zrzut ekranu w programie Photoshop. Obraz jest teraz naprawiony.
inserttusernamehere

@Giles - Doceń swój komentarz, w SO byłoby to całkowicie właściwe, ale tutaj nie zmieniamy programów innych - mówimy im w komentarzach.
Nie to, że Charles

7

C, 220 bajtów

x,y,r;f(n){
printf("P3 %d %d 255 ",(8<<n)-8,4<<n);
for(y=0;y<4<<n;++y)for(r=0;r<n;++r)for(x=0;x<8<<r;++x)
puts("110 170 90\0 116 196 96\0 0 0 0"+12*
(117-"` t5L\rL\ru5tst5` "[x>>r+2|(y>>r)%8*2]>>(x>>r)%4*2&3));}

Dodałem bezużyteczne znaki nowego dla czytelności, wynik jest bez tych znaków.

Definiuje funkcję, f(n)która wyprowadza zwykły obraz PPM na standardowe wyjście.


1
Z jakiegoś powodu odpowiedzi C są w mojej głowie dość eleganckie.
downrep_nation

7

Mathematica, 267 255 254 225 212 bajtów

G=10{11,17,9};Image@Join[##,2]&@@Table[Join@@Table[ImageData@ImageResize[Image[{t={g=G+{6,26,6},g,g,G,g,g,g,g},f={g,a=##&[G,G,G],a,g},e={g,b=0g,b,G,G,b,b,g},e,{a,a,G,g},{g,a,b,a},f,t}/255],4*2^j],2^(#-j)],{j,#}]&

Zaoszczędzono 29 42 bajtów dzięki Martinowi Enderowi

Sugestie dotyczące gry w golfa są mile widziane, szczególnie przy konstruowaniu tablicy 8 na 8 (na 3) s. Niestety nie ma ArrayResizeodpowiednika dla " " ImageResize, więc tablica musi zostać przekonwertowana na image ( Image) przed zmianą rozmiaru, a następnie z powrotem na tablicę ( ImageData) w celu wykonania modyfikacji Join.

Nie golfowany:

(* dark green, light green, black *)
G = 10 {11, 17, 9};
g = G + {6, 26, 6};
b = 0 g;

(* abbreviation for triple G sequence, top row, forehead, eye level *)
a = ##&[G, G, G];
t = {g, g, g, G, g, g, g, g};
f = {g, a, a, g};
e = {g, b, b, G, G, b, b, g};

(* slime *)
s =
  {
    t,
    f,
    e,
    e,
    {a, a, G, g},
    {g, a, b, a},
    f,
    t
  }/255;

(* jth column *)
c[n_, j_] := Join @@ Table[ImageData@ImageResize[Image[s], 4*2^j], 2^(n - j)]

(* final program *)
Image@Join[##, 2] & @@ Table[c[#, j], {j, #}] &

1
b=0g. Aby wygenerować s, może być krótsze zakodowanie wartości pikseli jako liczby podstawowej-3, ale musiałbym się upewnić. W międzyczasie można zapisać bajty nie definiując b, g, f, e, tdopóki ich potrzebują, i snie potrzebuje nazwy w ogóle i nie robi c. Do 2^(j-1)8możesz użyć 4*2^j. Stosując je wszystkie, kończę na 225 bajtach: pastebin.com/YnkUwvwV
Martin Ender

@MartinEnder Ogromna wdzięczność, to są bardzo dobre sugestie! (Uwaga dla siebie: unikaj nazywania rzeczy, jeśli to możliwe, w przeciwnym razie wykonaj zadanie przy pierwszym wystąpieniu (zamiast wcześniej).)
lastresort

Nie mam czasu, aby zrozumieć to całkowicie teraz, ale tutaj jest pomysł, aby uniknąć Image, ImageResize, ImageDatarzeczy. Ten bit wysadza tablicę 2 razy: #&@@{##&@@{#,#}&//@x}gdzie xjest tablica. Więc jeśli przechowujesz początkową siatkę 8x8 w zmiennej x, a następnie robisz to x=#&@@{##&@@{#,#}&//@x}po każdym użyciu, możesz dość łatwo generować kolejne płytki.
Martin Ender

Ups, to 4 bajty dłużej niż trzeba:#&[##&[#,#]&//@x]
Martin Ender

Hm, ja nie dostaję to jeszcze działa, ale można zaoszczędzić trochę więcej o: a) za pomocą ##~Join~2ib) f={g,a=##&[G,G,G],a,g}, a następnie zastąpić każde dalsze występowanie G,G,Gz atak dobrze.
Martin Ender

4

Python 2.7: 424 412 405 376 357 bajtów

Jestem trochę nowy w golfie ... proszę bardzo

from numpy import*
import PIL
def c(n,col):e=log2((col+8)/8)//1;r=2**e;t=2**(n-e-1);return tile(repeat(array([0x2df0777ca228b9c18447a6fb/3**i%3for i in range(64)],dtype=int8).reshape([8,8])[:,(col-(8*r-8))//r],r),t)
n=input();i=PIL.Image.fromarray(column_stack([c(n,col) for col in range(2**(n+3)-8)]),mode='P');i.putpalette('t\xc4`n\xaaZ'+' '*762);i.show()

bez golfa i testowane na długość ..

from numpy import*
import PIL

def c(n,col): #creates array for a given column
    s = array([0x2df0777ca228b9c18447a6fb/3**i%3for i in range(64)],dtype=int8).reshape([8,8]) #slime template (golfed inline)
    e=log2((col+8)/8)//1 #exponent for tiles and repititions
    r=2**e #number of repitions (scale factor)
    t=2**(n-e-1) #number of tiles (vertically)
    return tile(
            repeat(
             s[:,(col-(8*r-8))//r] #select appropriate column from template
              ,r) #repeat it r times
               ,t) #tile it t times

n = input()
arr = column_stack([c(n,col) for col in range(2**(n+3)-8)]) #create image array by stacking column function
i=PIL.Image.fromarray(arr,mode='P'); #colormap mode
i.putpalette('t\xc4`n\xaaZ'+' '*762); #set colormap
i.show()

s = r'''from numpy import*
import PIL
def c(n,col):e=log2((col+8)/8)//1;r=2**e;t=2**(n-e-1);return tile(repeat(array([0x2df0777ca228b9c18447a6fb/3**i%3for i in range(64)],dtype=int8).reshape([8,8])[:,(col-(8*r-8))//r],r),t)
n=input();i=PIL.Image.fromarray(column_stack([c(n,col) for col in range(2**(n+3)-8)]),mode='P');i.putpalette('t\xc4`n\xaaZ'+' '*762);i.show()'''

print len(s)

edit1: usunięto sys.argv[1]na korzyść, raw_input()aby zapisać dodatkową instrukcję importu

edit2: skrócony import PIL: usunięty from ImagedodanoPIL.

edit3: Dzięki @ Sherlock9 za kodowanie szesnastkowe szablonu szlamu

edit4: nie potrzebował funkcji def i był używany input()zamiastraw_input()


wszelkie sugestie są mile widziane :) szczególnie w celu zmniejszenia tablicy szablonów
Aaron

Coś jak użycie '0000100001111110111211100111111102211220022112200111111000001000'(tablica do tyłu) przekonwertowane z bazy 3 na bazę 16 0x2df0777ca228b9c18447a6fb. Przy tym numerze użyj takiego kodu, [0x2df0777ca228b9c18447a6fb//3**i%3 for i in range(64)]aby uzyskać liczby całkowite we właściwej kolejności.
Sherlock9,

Ach, w Pythonie 2 [0x2df0777ca228b9c18447a6fb/3**i%3for i in range(64)]może być lepiej.
Sherlock9,

Dzięki, że Sherlock9 jest nowy w golfie, czy mógłbyś wyjaśnić, jak działa ta (jak sądzę) zmiana kodu podstawowego?
Aaron

1
Drugą częścią jest odzyskanie tablicy z tego numeru 0x2df0777ca228b9c18447a6fb. To jest proste. Dla prostszego przykładu, aby uzyskać 0cyfrę th 01221100, po prostu podziel przez 3 0razy, a następnie weź ostatnią cyfrę (używając mod 3), aby uzyskać 0. Aby wziąć drugą cyfrę, podziel przez 3 2razy, a następnie mod 3, aby uzyskać 1. Zrozumienie listy dzieli się tylko 3 64razy, aby odzyskać pełną tablicę. Jeśli masz więcej pytań, możemy omówić je na czacie PPCG .
Sherlock9,

1

R, 378 356 346 334 bajtów

f=function(n){r=rep;k=r(0,4);m=r(1,6);L=c();for(i in 1:n)L=cbind(L,r(max(L,0)+2^(n-i):1,e=2^(i-1)));png(w=sum(w<-4*2^(1:n)),h=sum(h<-r(8,2^(n-1))));layout(L,w,h);for(i in 1:max(L)){par(mar=k);image(matrix(c(0,0,0,1,k,0,m,0,0,1,1,1,2,r(1,10),0,0,r(r(c(2,1,2,0),e=2),2),m,k,1,k),nr=8),col=c("#74C460","#6EAA5A",1),ax=F,an=F)};dev.off()}

Zapisuje jako plik png. Wcięte, z liniami:

f=function(n){
    r=rep
    k=r(0,4)
    m=r(1,6)
    L=c()
    for(i in 1:n)L=cbind(L,r(max(L,0)+2^(n-i):1,e=2^(i-1)))
    png(w=sum(w<-4*2^(1:n)),h=sum(h<-r(8,2^(n-1))))
    layout(L,w,h)
    for(i in 1:max(L)){
        par(mar=k)
        image(matrix(c(0,0,0,1,k,0,m,0,
                       0,1,1,1,2,r(1,10),0,
                       0,r(r(c(2,1,2,0),e=2),2),
                       m,k,1,k),
                     nr=8),
              col=c("#74C460","#6EAA5A",1),ax=F,an=F)
    }
    dev.off()
}

N = 2: N = 3: N = 4:N = 2
N = 3
N = 4

Kilka wyjaśnień:

Oto macierz, która jest drukowana (0 oznacza jasnozielony, 1 ciemnozielony i 2 czarny; matryca jest przechylona, ​​ponieważ kolumny są osi y i wiersze osi x):

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    0    0    0    1    0    0    0    0
[2,]    0    1    1    1    2    2    1    0
[3,]    0    1    1    1    2    2    1    0
[4,]    1    1    1    1    1    1    1    1
[5,]    0    1    2    1    1    1    1    0
[6,]    0    1    1    1    2    2    1    0
[7,]    0    1    1    1    2    2    1    0
[8,]    0    0    1    0    0    0    0    0

Każde wywołanie imagewykreślające tę macierz (z każdą liczbą całkowitą odpowiadającą kolorowi). Dla N = 4 tutaj jest L (matryca układu, każda niepowtarzalna liczba reprezentuje jeden pojedynczy wykres), w (szerokości kolumn macierzy) i h (wysokości rzędów macierzy):

> L
     [,1] [,2] [,3] [,4]
[1,]    8   12   14   15
[2,]    7   12   14   15
[3,]    6   11   14   15
[4,]    5   11   14   15
[5,]    4   10   13   15
[6,]    3   10   13   15
[7,]    2    9   13   15
[8,]    1    9   13   15
> w
[1]  8 16 32 64
> h
[1] 8 8 8 8 8 8 8 8
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.