Pemrograman Berlipit Secara Eksponensial: Susun Minecraft Slimes


108

Slimes adalah musuh berbentuk kubus di Minecraft yang membobol beberapa versi yang lebih kecil dari dirinya ketika terbunuh. Untuk keperluan tantangan ini, kami akan menggambarkannya sebagai gambar 8 × 8 piksel dengan 3 warna:

Lendir 64x64

8x8 lendir ← Benar versi 8 × 8.

Warna RGB yang tepat adalah:

  • 0, 0, 0 untuk mata dan mulut
  • 110, 170, 90 untuk pusat, hijau gelap
  • 116, 196, 96 untuk bagian luar, hijau muda

Tantangan

Tulis sebuah program atau fungsi yang mengambil dalam bilangan bulat positif N dan menghasilkan gambar ukuran N slimes dikemas ke dalam persegi panjang. Dari kiri ke kanan, gambar harus mengikuti pola memiliki:

  • Tumpukan 2 (N-1) 8 × 8 slimes.
  • Tumpukan 2 (N-2) 16 × 16 slimes.
  • Tumpukan 2 (N-3) 32 × 32 slimes.
  • Demikian seterusnya hingga stack hanya berisi satu slime.

Gambar slime yang lebih besar dari versi 8 × 8 ( 8x8 lendir) dihasilkan oleh upampling tetangga terdekat (yaitu hanya menggandakan semua piksel). Perhatikan bahwa Anda harus menggunakan desain lendir yang tepat dan warna yang diberikan di sini.

Gambar akhir akan berisi 2 N -1 slimes dan lebar 2 (N + 3) -8 piksel dan tinggi 2 (N + 2) piksel.

Gambar dapat berupa output dalam format file gambar apa pun, disimpan ke file atau dicetak / dikembalikan sebagai aliran data mentah, atau langsung ditampilkan selama runtime.

Kode terpendek dalam byte menang.

Contohnya

Program Anda harus menghasilkan hasil yang tepat ini.

N = 1:

N = 1

N = 2:

N = 2

N = 3:

N = 3

N = 4:

N = 4

N = 5:

N = 5

N = 6:

N = 6

N yang lebih besar seharusnya bekerja dengan baik.


30
Saya akan menang tapi saya tidak punya suara lagi. Saya meninggalkan komentar ini jadi saya akan ingat untuk memperbaiki besok.
NoOneIsHere

23
Saya memperbaiki komentar Anda karena saya juga kehabisan upvotes.
trichoplax

4
"Gambar slime yang lebih besar dari versi 8 × 8 () dihasilkan oleh tetangga terdekat (yaitu hanya menggandakan semua piksel)." Apakah maksud Anda melipatgandakan semua piksel, membuat setiap piksel menjadi kuadrat 2x2?
Caridorc

1
@Caridorc Menggandakan di setiap arah?
wizzwizz4

@ wizzwizz4 Ya, setiap piksel menjadi 4, benar?
Caridorc

Jawaban:


21

MATL , 77 76 74 byte

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

Kode berfungsi dalam komit ini , yang lebih awal dari tantangan.

Anda dapat mencobanya di MATL online . Penerjemah ini masih eksperimental. Jika tidak berhasil, coba segarkan halaman dan tekan "Run" lagi.

Berikut ini contoh yang dijalankan dalam penerjemah offline:

masukkan deskripsi gambar di sini

Penjelasan

:                     % 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

"N yang lebih besar seharusnya bekerja dengan baik juga.", Tetapi milikmu tampaknya memberikan Out Of Memory / indeks kesalahan sudah di n = 9. Apakah ini hanya penerjemah online, atau apakah ini terjadi dalam versi offline juga?
David Mulder

1
@ Davidvidul Saya telah menguji offline (compiler berjalan pada Matlab R2015b, Windows 7 64 bit, 4 GB RAM) untuk input hingga 11dan berfungsi. Untuk 11hasilnya adalah gambar 8192 × 16376. Untuk 12itu akan menjadi 16384 × 32760 (536 megapiksel), membutuhkan lebih dari 4 GB RAM, yang lebih dari yang bisa ditangani laptop saya.
Luis Mendo

2
Saya suka bagaimana kode dimulai dengan senyuman yang menahan air matanya karena emosi yang kuat yang membuat kode ini membuatnya merasa: "')
Tom Doodler

14

Dyalog APL, 118 113 byte

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

asumsi ⎕IO=0

Dari kanan ke kiri:

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

i{ }¨⌽iberalih pada kekuatan (dengan ) dan kekuatan terbalik ( )

⊤¨⍨⊂32⍴3 decode masing-masing angka di sebelah kiri sebagai 32 digit ternary

8 8⍴∊ ratakan dan bentuk kembali menjadi 8 × 8

⍺⌿⍺/meniru setiap baris dan kolom kali

⍵⍴⊂ambil salinan

⊃⍪/ dan menumpuknya secara vertikal

⊃,/ gabungkan semua hasil secara horizontal

3↑(116 196 96)(110 170 90)warna; 3↑memperpanjang mereka dengan(0 0 0)

[ ]indeks warna dengan masing-masing elemen matriks; hasilnya adalah matriks RGB

('P3',⌽∘⍴,255,∊)adalah "kereta" - fungsi yang mengembalikan 'P3'diikuti oleh bentuk argumen yang dibalik 255,, dan argumen diratakan.


Saya pikir Anda dapat menulis program Anda dengan asumsi ⎕IO←0dan hanya menyatakan sebagai syarat, di luar jumlah byte. Banyak sistem APL menggunakannya sebagai default. (Termasuk LOL milikmu)
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++,_,_)}}

Versi ES6 Tidak Serigala

Cobalah sendiri.

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

Satu-satunya perbedaan antara versi ES7 dan ES6 adalah menggunakan **bukan Math.pow(). Anda juga dapat melihat, bagaimana Anda dapat menjalankan fungsi - dalam contoh ini dengan n=4.

Hasil

masukkan deskripsi gambar di sini


Suntingan

  • disimpan 1 byte - menemukan tanda titik koma yang tidak perlu;

Ini sangat lambat dan mungkin membutuhkan waktu untuk angka yang lebih besar 10.


2
warnanya tampak sedikit tidak jelas pada gambar di sini. Apakah Anda mungkin tangkapan layar dengan f.lux aktif?
Jezzamon

@ Jezzamon Terima kasih telah menunjukkannya - saya juga memperhatikan itu. Ada sedikit kemungkinan bahwa saya mungkin telah memilih " Konversi warna dokumen ke ruang kerja " saat mengimpor tangkapan layar ke Photoshop. Gambar sudah diperbaiki sekarang.
masukkan nama pengguna di sini

@Giles - Hargai komentar Anda, dan dalam SO, itu benar-benar tepat, tapi di sini, kami tidak mengubah program orang lain - kami memberi tahu mereka dalam komentar.
Bukan berarti Charles

7

C, 220 byte

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

Saya menambahkan baris baru yang tidak berguna untuk dibaca, skor tanpa baris baru ini.

Menentukan fungsi f(n)yang menampilkan gambar PPM biasa di stdout.


1
Untuk beberapa alasan jawaban C cukup elegan dalam pikiran saya.
downrep_nation

7

Mathematica, 267 255 254 225 212 byte

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

Disimpan 29 42 byte berkat Martin Ender

Saran golf diterima, terutama untuk membangun array 8 oleh 8 (oleh 3) s. Sayangnya, tidak ada " ArrayResize" analog untuk ImageResize, jadi array perlu dikonversi ke gambar ( Image) sebelum mengubah ukuran, dan kemudian kembali ke array ( ImageData) untuk melakukan Joining.

Tidak Terkumpul:

(* 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. Untuk menghasilkannya smungkin lebih pendek untuk mengkodekan nilai piksel sebagai angka dasar-3 tetapi saya harus mencoba untuk memastikannya. Sementara itu, Anda dapat menyimpan byte dengan tidak mendefinisikan b, g, f, e, tsampai Anda membutuhkan mereka, dan stidak membutuhkan nama sama sekali dan juga tidak c. Untuk 2^(j-1)8bisa kamu gunakan 4*2^j. Menerapkan semua itu, saya berakhir pada 225 byte: pastebin.com/YnkUwvwV
Martin Ender

@ MartinEnder Banyak terima kasih, ini semua adalah saran yang sangat bagus! (Catatan untuk diri sendiri: hindari penamaan hal-hal jika memungkinkan, jika tidak lakukan penugasan di (daripada sebelumnya) kejadian pertama.)
lastresort

Saya tidak punya waktu untuk mencari tahu sepenuhnya sekarang, tapi di sini adalah ide untuk menghindari Image, ImageResize, ImageDatahal. Bit ini meledakkan array dengan faktor 2: di #&@@{##&@@{#,#}&//@x}mana xarray. Jadi jika Anda menyimpan grid 8x8 awal dalam sebuah variabel x, dan kemudian lakukan x=#&@@{##&@@{#,#}&//@x}setelah setiap penggunaan, Anda dapat membuat ubin berturut-turut dengan mudah.
Martin Ender

Aduh, itu 4 byte lebih lama dari yang seharusnya:#&[##&[#,#]&//@x]
Martin Ender

Hm, saya belum mendapatkan ini berfungsi, tetapi Anda dapat menyimpan lebih banyak dengan a) menggunakan ##~Join~2dan b) f={g,a=##&[G,G,G],a,g}dan kemudian mengganti setiap kejadian lebih lanjut G,G,Gdengan ajuga.
Martin Ender

4

Python 2.7: 424 412 405 376 357 Bytes

Saya agak baru dalam bermain golf .... ini dia

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 dan panjang diuji ..

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)

sunting1: dihapus sys.argv[1]demi raw_input()menyimpan pernyataan impor tambahan

sunting2: impor PIL singkat: dihapus from ImageditambahkanPIL.

edit3: Terima kasih @ Sherlock9 untuk enkode heks templat slime

sunting4: tidak perlu def fungsi dan digunakan input()sebagai gantinyaraw_input()


ada saran yang lebih dari diterima :) terutama untuk mengecilkan array template
Aaron

Sesuatu seperti menggunakan '0000100001111110111211100111111102211220022112200111111000001000'(array Anda mundur) dikonversi dari basis 3 ke basis 16 0x2df0777ca228b9c18447a6fb. Dengan nomor itu, gunakan kode seperti ini [0x2df0777ca228b9c18447a6fb//3**i%3 for i in range(64)]untuk mendapatkan bilangan bulat Anda dalam urutan yang benar.
Sherlock9

Ah, dengan Python 2, [0x2df0777ca228b9c18447a6fb/3**i%3for i in range(64)]mungkin lebih baik.
Sherlock9

Terima kasih @ Sherlock9 yang baru dalam bermain golf, dapatkah Anda menjelaskan bagaimana perubahan kode dasar ini (saya kira) berfungsi?
Aaron

1
Bagian kedua adalah untuk mendapatkan kembali array Anda dari nomor itu 0x2df0777ca228b9c18447a6fb. Ini sederhana. Sebagai contoh yang lebih sederhana, untuk mendapatkan 0digit ke-3 01221100, cukup bagi dengan 3 0kali, lalu ambil digit terakhir (menggunakan mod 3) untuk mendapatkan 0. Untuk mengambil digit ke-2, bagi dengan 3 2kali, lalu mod 3 untuk mendapatkan 1. Pemahaman daftar hanya dibagi 3 64kali untuk mendapatkan array penuh Anda kembali. Jika Anda memiliki pertanyaan lagi, kami dapat mendiskusikannya di obrolan PPCG .
Sherlock9

1

R, 378 356 346 334 byte

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

Menyimpan sebagai file png. Diindentasi, dengan umpan garis:

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

Beberapa penjelasan:

Inilah matriks yang sedang diplot (0 mewakili hijau muda, 1 hijau tua dan 2 hitam; matriks dimiringkan karena kolom adalah sumbu y dan baris sumbu 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

Setiap panggilan untuk imagememplot matriks itu (dengan masing-masing bilangan bulat sesuai dengan warna). Untuk N = 4, di sini adalah L (matriks tata letak, setiap nomor unik mewakili satu plot tunggal), w (lebar kolom matriks) dan h (ketinggian baris matriks):

> 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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.