Programmation exponentielle visqueuse: Empiler des slimes de Minecraft

108

Les boues sont des ennemis en forme de cube dans Minecraft qui se divisent en plusieurs versions plus petites d’eux-mêmes quand ils sont tués. Pour les besoins de ce défi, nous les représenterons comme une image 8 × 8 pixels avec 3 couleurs:

Slime 64x64

8x8 slime ← Véritable version 8 × 8.

Les couleurs RVB précises sont:

  • 0, 0, 0 pour les yeux et la bouche
  • 110, 170, 90 pour le centre, vert plus foncé
  • 116, 196, 96 pour l'extérieur, vert plus clair

Défi

Ecrivez un programme ou une fonction qui prend un entier positif N et génère une image de N tailles de slimes regroupées dans un rectangle. En allant de gauche à droite, l’image doit suivre le schéma suivant:

  • Une pile de 2 (N-1) 8 × 8 boues.
  • Une pile de 2 (N-2) 16 × 16 boues.
  • Une pile de 2 (N-3) 32 × 32 boues.
  • Et ainsi de suite jusqu'à ce que la pile ne contienne plus qu'un seul slime.

Les images visqueuses plus grandes que la version 8 × 8 ( 8x8 slime) sont générées par suréchantillonnage du voisin le plus proche (en doublant simplement tous les pixels). Notez que vous devez utiliser exactement le design et les couleurs de slime indiqués ici.

L'image finale contiendra 2 N -1 slimes et aura 2 (N + 3) -8 pixels de large et 2 (N + 2) pixels de haut.

L'image peut être sortie dans n'importe quel format de fichier d'image commun, enregistrée dans un fichier ou imprimée / renvoyée sous forme de flux de données brutes, ou directement affichée pendant l'exécution.

Le code le plus court en octets gagne.

Exemples

Votre programme devrait produire ces résultats exacts.

N = 1:

N = 1

N = 2:

N = 2

N = 3:

N = 3

N = 4:

N = 4

N = 5:

N = 5

N = 6:

N = 6

Un plus grand N devrait aussi bien fonctionner.

Les passe-temps de Calvin
la source
30
Je voterais mais je n'ai plus de voix. Je laisse ce commentaire, je me souviendrai donc de faire un vote par appel nominal demain.
NoOneIsHere
23
Je vote votre commentaire parce que je suis à court de upvotes aussi.
Trichoplax
4
"Les images visqueuses plus grandes que la version 8 × 8 () sont générées par suréchantillonnage du voisin le plus proche (c'est-à-dire qu'il double tout simplement tous les pixels)." Voulez-vous dire quadruple tous les pixels, transformez chaque pixel en un carré de 2x2?
Caridorc
1
@Caridorc Doubler dans chaque direction?
wizzwizz4
@ wizzwizz4 Oui, chaque pixel devient 4, correct?
Caridorc

Réponses:

21

MATL , 77 76 74 octets

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

Le code fonctionne dans ce commit , qui est antérieur au défi.

Vous pouvez l'essayer dans MATL en ligne . Cet interprète est encore expérimental. Si cela ne fonctionne pas, essayez d'actualiser la page et d'appuyer à nouveau sur "Exécuter".

Voici un exemple exécuté dans l'interpréteur hors ligne:

entrez la description de l'image ici

Explication

:                     % 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
la source
"N plus grand devrait aussi bien fonctionner.", Mais le vôtre semble donner des erreurs de mémoire insuffisante / index déjà à n = 9. S'agit-il uniquement de l'interpréteur en ligne ou existe-t-il également dans la version hors connexion?
David Mulder
1
@ DavidMulder J'ai testé hors ligne (compilateur fonctionnant sur Matlab R2015b, Windows 7 64 bits, 4 Go de RAM) pour l'entrée jusqu'à 11et cela fonctionne. Pour 11le résultat est une image 8192 × 16376. Car 12ce serait 16384 × 32760 (536 mégapixels), nécessitant plus de 4 Go de RAM, ce qui est plus que ce que mon ordinateur portable peut gérer.
Luis Mendo
2
J'aime la façon dont le code commence par un smiley qui retient ses larmes à cause des émotions intenses que ce code lui fait ressentir: "')
Tom Doodler
14

Dyalog APL, 118 113 octets

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

en supposant ⎕IO=0

De droite à gauche:

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

i{ }¨⌽iitérer sur les pouvoirs (avec ) et les pouvoirs inversés ( )

⊤¨⍨⊂32⍴3 décoder chacun des nombres à gauche en 32 chiffres ternaires

8 8⍴∊ aplatir et remodeler à 8 × 8

⍺⌿⍺/reproduire chaque rangée et colonne fois

⍵⍴⊂prendre des copies

⊃⍪/ et les empiler verticalement

⊃,/ joindre tous les résultats horizontalement

3↑(116 196 96)(110 170 90)couleurs; 3↑les étend avec(0 0 0)

[ ]indexer les couleurs avec chaque élément de la matrice; le résultat est une matrice de RVB

('P3',⌽∘⍴,255,∊)est un "train" - une fonction qui retourne 'P3'suivie de la forme inversée de l'argument 255et de l'argument aplati.

ngn
la source
Je pense que vous pouvez écrire votre programme en supposant ⎕IO←0et le déclarer simplement comme une condition, en dehors du nombre d'octets. De nombreux systèmes APL utilisent cela par défaut. (Y compris le vôtre LOL)
Tobia
11

JavaScript (ES7), 326 327 octets

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

Version ES6 Ungolfed

Essayez vous-même.

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

La seule différence entre les versions ES7 et ES6 est d'utiliser **au lieu de Math.pow(). Vous pouvez également voir comment appeler la fonction - dans cet exemple avec n=4.

Résultat

entrez la description de l'image ici


Édite

  • sauvé 1 octet - a trouvé un point-virgule final inutile;

Ceci est assez lent et peut prendre un certain temps pour des nombres supérieurs à 10.

insertusernamehere
la source
2
les couleurs semblent légèrement décalées dans l'image ici. Avez-vous peut-être effectué une capture d'écran avec f.lux?
Jezzamon
@ Jezzamon Merci de l'avoir signalé - je l'ai aussi remarqué. Il y a une faible possibilité que je pourrais avoir choisi « Convertir les couleurs du document à l'espace de travail » lors de l' importation de la capture d' écran dans Photoshop. L'image est corrigée maintenant.
insertusernamehere
@Giles - Appréciez votre commentaire, et dans SO, ce serait tout à fait approprié, mais ici, nous ne changeons pas les programmes des autres, nous leur disons dans des commentaires.
Pas que Charles
7

C, 220 octets

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

J'ai ajouté des nouvelles lignes inutiles pour la lisibilité, le score est sans ces nouvelles lignes.

Définit une fonction f(n)qui génère une image PPM simple sur stdout.

orlp
la source
1
Pour une raison quelconque, les réponses C sont assez élégantes dans mon esprit.
downrep_nation
7

Mathematica, 267 255 254 225 212 octets

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

Sauvegardé 29 42 octets grâce à Martin Ender

Des suggestions de golf sont les bienvenues, en particulier pour la construction du tableau 8 x 8 (sur 3) s. Malheureusement, il n’existe pas d’ ArrayResizeanalogue pour ImageResize, le tableau doit donc être converti en image ( Image) avant de redimensionner, puis de nouveau en tableau ( ImageData) Join.

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, #}] &
dernier recours
la source
1
b=0g. Pour le générer, sil serait peut-être plus court de coder les valeurs de pixel sous forme de nombre en base 3, mais je devrais essayer d'être sûr. En attendant, vous pouvez économiser des octets en ne définissant pas b, g, f, e, tjusqu'à ce que vous avez besoin, et sn'a pas besoin d' un nom à tous et ne fait c. Pour que 2^(j-1)8vous puissiez utiliser 4*2^j. En appliquant tous ceux-ci, je me retrouve à 225 octets: pastebin.com/YnkUwvwV
Martin Ender
@MartinEnder Beaucoup de gratitude, ce sont toutes de très bonnes suggestions! (Note to self: évitez de nommer des choses si possible, sinon faites l'affectation à (plutôt qu'avant) la première fois.)
lastresort
Je n'ai pas le temps de le comprendre complètement en ce moment, mais voici une idée pour éviter Image, ImageResize, des ImageDatachoses. Ce bit gonfle un tableau d'un facteur 2: #&@@{##&@@{#,#}&//@x}xest le tableau. Donc, si vous stockez la grille 8x8 initiale dans une variable x, puis x=#&@@{##&@@{#,#}&//@x}après chaque utilisation, vous pouvez générer les tuiles successives assez facilement.
Martin Ender
Oups, c'est 4 octets de plus que nécessaire:#&[##&[#,#]&//@x]
Martin Ender
Hm, je ne comprends pas encore si cela fonctionne, mais vous pouvez en économiser un peu plus en a) en utilisant ##~Join~2et en b) f={g,a=##&[G,G,G],a,g}, puis remplacez chaque nouvelle occurrence de G,G,Gpar a.
Martin Ender
4

Python 2.7: 424 412 405 376 357 octets

Je suis un peu nouveau au golf .... on y va

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 et longueur testé.

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: supprimé sys.argv[1]en faveur de l' raw_input()enregistrement d'une déclaration d'importation supplémentaire

edit2: importation abrégée de PIL: supprimé from ImageajoutéPIL.

edit3: Merci @ Sherlock9 pour le code hexadécimal du modèle slime

edit4: n'a pas besoin de la fonction def et utilisé à la input()place deraw_input()

Aaron
la source
toutes les suggestions sont les bienvenues :) en particulier pour réduire la matrice de modèles
Aaron
Quelque chose comme utiliser '0000100001111110111211100111111102211220022112200111111000001000'(votre tableau en arrière) converti de la base 3 à la base 16 0x2df0777ca228b9c18447a6fb. Avec ce nombre, utilisez un code comme celui-ci [0x2df0777ca228b9c18447a6fb//3**i%3 for i in range(64)]pour obtenir vos nombres entiers dans le bon ordre.
Sherlock9
Ah, en Python 2, [0x2df0777ca228b9c18447a6fb/3**i%3for i in range(64)]peut-être mieux.
Sherlock9
Merci @ Sherlock9 étant nouveau dans le golf, pourriez-vous expliquer comment ce changement (je suppose) du code de base fonctionne?
Aaron
1
La deuxième partie consiste à récupérer votre tableau à partir de ce nombre 0x2df0777ca228b9c18447a6fb. C'est simple. Pour obtenir un exemple plus simple, pour obtenir le 0e chiffre de 01221100, divisez simplement par 3 0, puis prenez le dernier chiffre (en utilisant le mod 3) à obtenir 0. Pour prendre le deuxième chiffre, divisez par 3 2fois, puis mod 3 pour obtenir 1. La compréhension de la liste se divise simplement par 3 64fois pour récupérer votre tableau complet. Si vous avez d'autres questions, nous pouvons en discuter dans le chat du PPCG .
Sherlock9
1

R, 378 356 346 334 octets

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

Enregistre en tant que fichier png. En retrait, avec sauts de ligne:

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

Quelques explications:

Voici la matrice en cours de tracé (0 représente le vert clair, 1 le vert foncé et 2 le noir; la matrice est inclinée car les colonnes sont l'axe des y et les lignes l'axe des 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

Chaque appel à imagetracer cette matrice (chaque entier correspondant à une couleur). Pour N = 4, voici L (la matrice de présentation, chaque numéro unique représente un seul tracé), w (les largeurs des colonnes de la matrice) et h (les hauteurs des lignes de la matrice):

> 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
planificateur
la source