Exponentiell schleimiges Programmieren: Stapeln von Minecraft Slimes

108

Schleime sind würfelförmige Feinde in Minecraft , die beim Töten in mehrere kleinere Versionen von sich selbst zerfallen. Für diese Herausforderung stellen wir sie als 8 × 8-Pixel-Bild mit drei Farben dar:

64x64 Schleim

8x8 Schleim ← Echte 8 × 8-Version.

Die genauen RGB-Farben sind:

  • 0, 0, 0 für die Augen und den Mund
  • 110, 170, 90 für das zentrale, dunklere Grün
  • 116, 196, 96 für das äußere, hellere Grün

Herausforderung

Schreiben Sie ein Programm oder eine Funktion, die eine positive ganze Zahl N aufnimmt und ein Bild mit N in ein Rechteck gepackten Schleimgrößen ausgibt. Von links nach rechts sollte das Bild dem Muster folgen:

  • Ein Stapel von 2 (N-1) 8 × 8 Schleimen.
  • Ein Stapel von 2 (N-2) 16 × 16 Schleimen.
  • Ein Stapel von 2 (N-3) 32 × 32 Schleimen.
  • Und so weiter, bis der Stapel nur noch einen Schleim enthält.

Die Schleimbilder, die größer als die 8 × 8-Version ( 8x8 Schleim) sind, werden durch Aufwärtsabtasten des nächsten Nachbarn (dh nur Verdoppeln aller Pixel) erzeugt. Beachten Sie, dass Sie das genaue Schleimdesign und die Farben verwenden müssen, die hier angegeben sind.

Das endgültige Bild enthält 2 N -1 Schleime und ist 2 (N + 3) -8 Pixel breit und 2 (N + 2) Pixel hoch.

Das Bild kann in jedem gängigen Bilddateiformat ausgegeben, in einer Datei gespeichert oder als Rohdatenstrom gedruckt / zurückgegeben oder zur Laufzeit direkt angezeigt werden.

Der kürzeste Code in Bytes gewinnt.

Beispiele

Ihr Programm sollte genau diese Ergebnisse liefern.

N = 1:

N = 1

N = 2:

N = 2

N = 3:

N = 3

N = 4:

N = 4

N = 5:

N = 5

N = 6:

N = 6

Größere N sollten genauso gut funktionieren.

Calvins Hobbys
quelle
30
Ich würde stimmen, aber ich habe keine Stimmen mehr. Ich hinterlasse diesen Kommentar, damit ich mich daran erinnere, morgen zu stimmen.
NoOneIsHere
23
Ich stimme deinem Kommentar zu, weil mir auch die Stimmen ausgehen.
Trichoplax
4
"Die Schleimbilder, die größer als die 8 × 8-Version () sind, werden durch Aufwärtsabtasten beim nächsten Nachbarn erzeugt (dh nur Verdoppelung aller Pixel)." Meinten Sie alle Pixel vervierfachen, jedes Pixel zu einem 2x2-Quadrat machen?
Caridorc
1
@Caridorc In jede Richtung verdoppeln?
Wizzwizz4
@ wizzwizz4 Ja, jedes Pixel wird zu 4, richtig?
Caridorc

Antworten:

21

MATL , 77 76 74 Bytes

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

Der Code funktioniert in dieser Festschreibung , die vor der Herausforderung liegt.

Sie können es in MATL online ausprobieren . Dieser Interpreter ist noch experimentell. Wenn es nicht funktioniert, aktualisieren Sie die Seite und drücken Sie erneut auf "Ausführen".

Hier ist ein Beispiel, das im Offline-Interpreter ausgeführt wird:

Bildbeschreibung hier eingeben

Erläuterung

:                     % 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
Luis Mendo
quelle
"Größeres N sollte genauso gut funktionieren.", Aber bei Ihrem scheint es bereits bei n = 9 zu Speicher- / Indexfehlern zu kommen. Ist dies nur der Online-Interpreter, oder passiert dies auch in der Offline-Version?
David Mulder
1
@DavidMulder Ich habe offline getestet (Compiler läuft auf Matlab R2015b, Windows 7 64 Bit, 4 GB RAM) 11und es funktioniert. Für 11das Ergebnis ist ein 8192 × 16376 Bild. Dafür 12wären 16384 × 32760 (536 Megapixel) erforderlich, was mehr als 4 GB RAM bedeutet, als mein Laptop verarbeiten kann.
Luis Mendo
2
Mir gefällt, wie der Code mit einem Smiley beginnt, der seine Tränen
Tom Doodler
14

Dyalog APL, 118 113 Bytes

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

vorausgesetzt ⎕IO=0

Von rechts nach links:

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

i{ }¨⌽iüber Potenzen (mit ) und umgekehrte Potenzen ( ) iterieren

⊤¨⍨⊂32⍴3 Dekodieren Sie jede der Zahlen auf der linken Seite als 32 ternäre Ziffern

8 8⍴∊ Abflachen und auf 8 × 8 umformen

⍺⌿⍺/Replizieren jede Zeile und Spalte Zeiten

⍵⍴⊂nehmen Kopien

⊃⍪/ und stapeln sie vertikal

⊃,/ Verbinden Sie alle Ergebnisse horizontal

3↑(116 196 96)(110 170 90)Farben; 3↑erweitert sie mit(0 0 0)

[ ]Indizieren Sie die Farben mit jedem Element der Matrix. Ergebnis ist eine Matrix von RGBs

('P3',⌽∘⍴,255,∊)ist ein "Zug" - eine Funktion, die zurückgegeben wird, 'P3'gefolgt von der umgekehrten Form des Arguments 255und dem abgeflachten Argument.

ngn
quelle
Ich denke, Sie können Ihr Programm unter der Annahme schreiben ⎕IO←0und es nur als Bedingung außerhalb der Bytezahl angeben. Viele APL-Systeme verwenden dies als Standard. (Einschließlich Ihrer LOL)
Tobia
11

JavaScript (ES7), 326 327 Byte

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++,_,_)}}

Ungolfed ES6 Version

Versuch es selber.

(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);

Der einzige Unterschied zwischen der ES7- und der ES6-Version besteht in der Verwendung **von Math.pow(). Sie können auch sehen, wie Sie die Funktion aufrufen können - in diesem Beispiel mit n=4.

Ergebnis

Bildbeschreibung hier eingeben


Bearbeitungen

  • 1 Byte gespeichert - Es wurde ein unnötiges nachgestelltes Semikolon gefunden;

Dies ist ziemlich langsam und kann bei Zahlen über 10 einige Zeit in Anspruch nehmen.

insertusernamehere
quelle
2
Die Farben scheinen hier auf dem Bild leicht abzulaufen. Hast du vielleicht einen Screenshot mit f.lux gemacht?
Jezzamon
@Jezzamon Danke für den Hinweis - das habe ich auch gemerkt. Es gibt eine geringe Möglichkeit , dass ich vielleicht haben sich entschieden , „ Dokument der Farben in den Arbeitsraum konvertieren “ , während Sie den Screenshot in Photoshop importieren. Das Bild ist jetzt fixiert.
Insertusernamehere
@Giles - Schätzen Sie Ihren Kommentar, und in SO wäre das völlig angemessen, aber hier ändern wir nicht die Programme anderer - wir sagen es ihnen in Kommentaren.
Nicht dass Charles
7

C 220 Bytes

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

Ich habe nutzlose Zeilenumbrüche hinzugefügt, um die Lesbarkeit zu verbessern. Die Punktzahl ist ohne diese Zeilenumbrüche.

Definiert eine Funktion f(n), die ein einfaches PPM-Bild auf Standardausgabe ausgibt.

orlp
quelle
1
Aus irgendeinem Grund sind C-Antworten in meinen Augen ziemlich elegant.
Downrep_nation
7

Mathematica, 267 255 254 225 212 Bytes

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,#}]&

29 42 Bytes dank Martin Ender gespeichert

Golfvorschläge sind willkommen, insbesondere für die Konstruktion des 8 x 8 (x 3) Arrays s. Leider gibt es kein " ArrayResize" Analogon für ImageResize, daher muss das Array Imagevor dem Ändern der Größe in ein Bild ( ) und anschließend wieder in ein Array ( ImageData) konvertiert werden, " " um die Größe zu Joinändern.

Ungolfed:

(* 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, #}] &
letzter Ausweg
quelle
1
b=0g. Um ses zu generieren, ist es möglicherweise kürzer, die Pixelwerte als Zahl zur Basis 3 zu codieren, aber ich müsste versuchen, sicher zu sein. In der Zwischenzeit können Sie Bytes nicht definiert , speichern b, g, f, e, tbis Sie sie benötigen, und sbrauchen keinen Namen überhaupt nicht und auch nicht c. Denn 2^(j-1)8du kannst verwenden 4*2^j. Wenn ich all das anwende, lande
Martin Ender
@MartinEnder Vielen Dank, das sind alles sehr gute Vorschläge! (Hinweis für sich selbst: Vermeiden Sie es, Dinge zu benennen, wenn dies möglich ist, andernfalls führen Sie die Zuweisung beim ersten Auftreten (und nicht vorher) durch.)
lastresort
Ich habe es nicht Zeit , um herauszufinden vollständig im Augenblick, aber hier ist eine Idee , die zu vermeiden Image, ImageResize, ImageDataSachen. Dieses Bit vergrößert ein Array um den Faktor 2: #&@@{##&@@{#,#}&//@x}Wo xist das Array? Wenn Sie also das anfängliche 8x8-Raster in einer Variablen speichern xund x=#&@@{##&@@{#,#}&//@x}nach jeder Verwendung erneut ausführen, können Sie die nachfolgenden Kacheln ganz einfach generieren.
Martin Ender
Hoppla, das sind 4 Bytes mehr als es sein muss:#&[##&[#,#]&//@x]
Martin Ender
Hm, ich bekomme das noch nicht zum Laufen, aber Sie können noch etwas sparen, indem Sie a) ##~Join~2und b) verwenden f={g,a=##&[G,G,G],a,g}und dann jedes weitere Vorkommen von G,G,Gmit ersetzen a.
Martin Ender
4

Python 2.7: 424 412 405 376 357 Bytes

Ich bin ein bisschen neu im Golfen ... los geht's

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()

ungolfed und länge getestet ..

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: sys.argv[1]wurde zugunsten von entfernt raw_input(), um zusätzliche Importanweisungen zu speichern

edit2: verkürzter PIL-Import: entfernt from ImagehinzugefügtPIL.

edit3: Danke @ Sherlock9 für die hexadezimale Kodierung der Schleimvorlage

edit4: brauchte keine Funktion def und verwendet input()stattraw_input()

Aaron
quelle
Anregungen sind mehr als willkommen :) Vor allem, um das Template-Array zu verkleinern
Aaron
So etwas wie "using" '0000100001111110111211100111111102211220022112200111111000001000'(Ihr Array rückwärts) konvertierte von Basis 3 zu Basis 16 0x2df0777ca228b9c18447a6fb. Verwenden Sie mit dieser Nummer den folgenden Code [0x2df0777ca228b9c18447a6fb//3**i%3 for i in range(64)], um Ihre Ganzzahlen in der richtigen Reihenfolge abzurufen.
Sherlock9
Ah, in Python 2 ist es [0x2df0777ca228b9c18447a6fb/3**i%3for i in range(64)]vielleicht besser.
Sherlock9
Dank @ Sherlock9, der neu im Golfsport ist, können Sie erklären, wie diese (ich nehme an) Änderung des Basiscodes funktioniert?
Aaron
1
Der zweite Teil besteht darin, Ihr Array von dieser Nummer zurückzubekommen 0x2df0777ca228b9c18447a6fb. Das ist ganz einfach. Für ein einfacheres Beispiel, um die 0th Ziffer von zu erhalten 01221100, dividieren Sie einfach durch 3 0und nehmen Sie dann die letzte Ziffer (mit Mod 3), um zu erhalten 0. Um die 2. Ziffer zu nehmen, dividiere durch 3 2mal, dann um Mod 3 zu erhalten 1. Das Listenverständnis wird nur 64dreimal geteilt, um das gesamte Array wiederherzustellen. Wenn Sie weitere Fragen haben, können wir diese im PPCG-Chat diskutieren .
Sherlock9
1

R, 378 356 346 334 Bytes

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

Speichert als PNG-Datei. Eingerückt, mit Zeilenvorschub:

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

Einige Erklärungen:

Hier ist die geplottete Matrix (0 steht für Hellgrün, 1 für Dunkelgrün und 2 für Schwarz; die Matrix ist geneigt, da Spalten die y-Achse und Zeilen die x-Achse sind):

     [,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

Jeder Aufruf zum imageZeichnen dieser Matrix (wobei jede Ganzzahl einer Farbe entspricht). Für N = 4 ist hier L (die Layoutmatrix, jede eindeutige Nummer steht für ein einzelnes Diagramm), w (die Breiten der Matrixspalten) und h (die Höhen der Matrixzeilen):

> 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
Plannapus
quelle