Lập trình theo cấp số nhân: Xếp chồng Slime Minecraft


108

Slimekẻ thù hình khối trong Minecraft , phá vỡ thành nhiều phiên bản nhỏ hơn của chúng khi bị giết. Với mục đích của thử thách này, chúng tôi sẽ mô tả chúng dưới dạng hình ảnh 8 × 8 pixel với 3 màu:

Chất nhờn 64x64

Chất nhờn 8 x 8 ← Phiên bản 8 × 8 đúng.

Các màu RGB chính xác là:

  • 0, 0, 0 cho mắt và miệng
  • 110, 170, 90 cho trung tâm, màu xanh đậm hơn
  • 116, 196, 96 cho bên ngoài, màu xanh nhạt hơn

Thử thách

Viết chương trình hoặc hàm lấy số nguyên dương N và xuất ra hình ảnh có kích thước N của các slime được đóng gói thành hình chữ nhật. Đi từ trái sang phải, hình ảnh phải theo mô hình có:

  • Một chồng gồm 2 (N-1) 8 × 8 slime.
  • Một chồng 2 slime 2 (N-2) 16 × 16.
  • Một chồng 2 slime 2 (N-3) 32 × 32.
  • Và cứ như vậy cho đến khi ngăn xếp chỉ chứa một chất nhờn.

Các hình ảnh chất nhờn lớn hơn phiên bản 8 × 8 ( Chất nhờn 8 x 8) được tạo ra bằng cách lấy mẫu lân cận gần nhất (nghĩa là chỉ nhân đôi tất cả các pixel). Lưu ý rằng bạn phải sử dụng thiết kế chất nhờn chính xác và màu sắc được đưa ra ở đây.

Hình ảnh cuối cùng sẽ chứa 2 N -1 slime và rộng 2 (N + 3) -8 pixel và cao 2 (N + 2) pixel.

Hình ảnh có thể được xuất ra ở bất kỳ định dạng tệp hình ảnh phổ biến nào, được lưu vào một tệp hoặc được in / trả lại dưới dạng luồng dữ liệu thô hoặc được hiển thị trực tiếp trong thời gian chạy.

Mã ngắn nhất tính bằng byte thắng.

Ví dụ

Chương trình của bạn sẽ tạo ra những kết quả chính xác.

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 lớn hơn nên làm việc như là tốt.


30
Tôi sẽ upvote nhưng tôi không còn phiếu. Tôi sẽ để lại bình luận này vì vậy tôi sẽ nhớ upvote vào ngày mai.
NoOneIsHãy là

23
Tôi đang nâng cao nhận xét của bạn vì tôi cũng đã hết những người ủng hộ.
trichoplax

4
"Các hình ảnh chất nhờn lớn hơn phiên bản 8 × 8 () được tạo ra bằng cách lấy mẫu lân cận gần nhất (nghĩa là chỉ nhân đôi tất cả các pixel)." Ý của bạn là tăng gấp bốn lần tất cả các pixel, biến mỗi pixel thành một hình vuông 2x2?
Caridorc

1
@Caridorc Nhân đôi theo từng hướng?
wizzwizz4

@ wizzwizz4 Có, mỗi pixel trở thành 4, đúng không?
Caridorc

Câu trả lời:


21

MATL , 77 76 74 byte

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

Mã này hoạt động trong cam kết này , sớm hơn thử thách.

Bạn có thể thử nó trong MATL trực tuyến . Thông dịch viên này vẫn còn thử nghiệm. Nếu nó không hoạt động, hãy thử làm mới trang và nhấn "Chạy" lại.

Dưới đây là một ví dụ chạy trong trình thông dịch ngoại tuyến:

nhập mô tả hình ảnh ở đây

Giải trình

:                     % 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 lớn hơn cũng sẽ hoạt động tốt.", Nhưng dường như bạn đã hết lỗi Bộ nhớ / chỉ số ở mức n = 9. Đây có phải chỉ là trình thông dịch trực tuyến hay điều này cũng xảy ra trong phiên bản ngoại tuyến?
David Mulder

1
@DavidMulder Tôi đã thử nghiệm ngoại tuyến (trình biên dịch chạy trên Matlab R2015b, Windows 7 64 bit, RAM 4 GB) để nhập vào 11và nó hoạt động. Cho 11kết quả là một hình ảnh 8192 × 16376. Đối với 12nó sẽ là 16384 × 32760 (536 megapixel), cần trên 4 GB RAM, nhiều hơn máy tính xách tay của tôi có thể xử lý.
Luis Mendo

2
Tôi thích cách mã bắt đầu bằng một nụ cười đang kìm nước mắt vì những cảm xúc mãnh liệt mà mã này khiến anh ấy cảm thấy: "')
Tom Doodler

14

APL Dyalog, 118 113 byte

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

giả định ⎕IO=0

Từ phải qua trái:

i←2*⍳⎕ quyền hạn 1 2 4 ... 2 n-1

i{ }¨⌽iLặp lại các quyền hạn (với ) và các quyền hạn đảo ngược ( )

⊤¨⍨⊂32⍴3 giải mã mỗi số bên trái là 32 chữ số thứ ba

8 8⍴∊ làm phẳng và định hình lại thành 8 × 8

⍺⌿⍺/nhân rộng mỗi hàng và thời gian cột

⍵⍴⊂lấy bản sao

⊃⍪/ và xếp chúng theo chiều dọc

⊃,/ tham gia tất cả các kết quả theo chiều ngang

3↑(116 196 96)(110 170 90)màu sắc; 3↑mở rộng chúng với(0 0 0)

[ ]lập chỉ mục màu sắc với từng yếu tố của ma trận; kết quả là một ma trận RGB

('P3',⌽∘⍴,255,∊)là một "chuyến tàu" - một hàm trả về 'P3'sau hình dạng đảo ngược của đối số 255và đối số được làm phẳng.


Tôi nghĩ rằng bạn có thể viết chương trình giả định ⎕IO←0và chỉ nêu nó như một điều kiện, ngoài số byte. Nhiều hệ thống APL sử dụng như một mặc định. (Bao gồm cả LOL của bạn)
Tobia

11

JavaScript (ES7), 327 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++,_,_)}}

Phiên bản ES6 đã bị hủy

Hãy thử nó.

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

Sự khác biệt duy nhất giữa phiên bản ES7 và ES6 là sử dụng **thay vì Math.pow(). Bạn cũng có thể thấy, làm thế nào bạn có thể gọi hàm - trong ví dụ này với n=4.

Kết quả

nhập mô tả hình ảnh ở đây


Chỉnh sửa

  • đã lưu 1 byte - tìm thấy một dấu chấm phẩy không cần thiết;

Điều này khá chậm và có thể mất một thời gian cho các số lớn hơn 10.


2
màu sắc có vẻ hơi tắt trong hình ảnh ở đây. Bạn có thể chụp màn hình với f.lux trên?
Jezzamon

@Jezzamon Cảm ơn bạn đã chỉ ra - Tôi cũng đã nhận thấy điều đó. Có một khả năng nhỏ là tôi có thể đã chọn " Chuyển đổi màu của tài liệu sang không gian làm việc " trong khi nhập ảnh chụp màn hình vào Photoshop. Hình ảnh được cố định bây giờ.
insertusernamehere

@Giles - Đánh giá cao nhận xét của bạn và trong SO, điều đó hoàn toàn phù hợp, nhưng ở đây, chúng tôi không thay đổi chương trình của người khác - chúng tôi nói với họ trong các nhận xét.
Không phải 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));}

Tôi đã thêm những dòng mới vô dụng để dễ đọc, điểm số không có những dòng mới này.

Xác định chức năng f(n)tạo ra hình ảnh PPM đơn giản trên thiết bị xuất chuẩn.


1
Đối với một số lý do C câu trả lời là khá thanh lịch trong tâm trí của tôi.
downrep_nation

7

Toán học, 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,#}]&

Đã lưu 29 42 byte nhờ Martin Ender

Đề nghị chơi gôn được chào đón, đặc biệt là để xây dựng mảng 8 x 8 (3) s. Thật không may, không có ArrayResizetương tự "" ImageResize, vì vậy mảng cần phải được chuyển đổi thành hình ảnh ( Image) trước khi thay đổi kích thước, sau đó quay lại mảng ( ImageData) để thực hiện Joining.

Ung dung:

(* 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. Để tạo ra snó có thể ngắn hơn để mã hóa các giá trị pixel dưới dạng số cơ sở 3 nhưng tôi phải cố gắng chắc chắn. Trong khi đó, bạn có thể tiết kiệm byte bằng cách không xác định b, g, f, e, tcho đến khi bạn cần đến chúng, và skhông cần một tên nào cả và cũng như thế c. Để 2^(j-1)8bạn có thể sử dụng 4*2^j. Áp dụng tất cả những thứ đó, tôi kết thúc ở mức 225 byte: pastebin.com/YnkUwvwV
Martin Ender

@MartinEnder Rất biết ơn, đây đều là những gợi ý rất hay! (Lưu ý đến bản thân: tránh đặt tên mọi thứ nếu có thể, nếu không hãy thực hiện nhiệm vụ tại (chứ không phải trước đó) lần đầu tiên xảy ra.)
Lastresort

Tôi không có thời gian để tìm nó ra hoàn toàn ngay bây giờ, nhưng đây là một ý tưởng để tránh Image, ImageResize, ImageDatathứ. Bit này làm nổ tung một mảng theo hệ số 2: mảng #&@@{##&@@{#,#}&//@x}đó ở đâu x. Vì vậy, nếu bạn lưu trữ lưới 8x8 ban đầu trong một biến x, và sau đó thực hiện x=#&@@{##&@@{#,#}&//@x}sau mỗi lần sử dụng, bạn có thể tạo các ô liên tiếp khá dễ dàng.
Martin Ender

Rất tiếc, đó là 4 byte dài hơn mức cần thiết:#&[##&[#,#]&//@x]
Martin Ender

Hm, tôi không nhận được để làm việc này, nhưng bạn có thể tiết kiệm một số chi tiết bằng a) sử dụng ##~Join~2và b) f={g,a=##&[G,G,G],a,g}và sau đó thay thế từng xảy ra hơn nữa G,G,Gvới alà tốt.
Martin Ender

4

Python 2.7: 424 412 405 376 357 byte

Tôi hơi mới chơi golf .... chúng ta đi nào

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

không kiểm tra và chiều dài thử nghiệm ..

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)

chỉnh sửa1: loại bỏ có sys.argv[1]lợi raw_input()để lưu báo cáo nhập thêm

edit2: rút ngắn PIL nhập khẩu: gỡ bỏ from ImagethêmPIL.

chỉnh sửa3: Cảm ơn @ Sherlock9 về mã hóa hex của mẫu chất nhờn

chỉnh sửa4: không cần chức năng def và được sử dụng input()thay vìraw_input()


mọi đề xuất đều được chào đón nhiều hơn :) đặc biệt là thu nhỏ mảng mẫu
Aaron

Một cái gì đó như sử dụng '0000100001111110111211100111111102211220022112200111111000001000'(mảng của bạn ngược) được chuyển đổi từ cơ sở 3 sang cơ sở 16 0x2df0777ca228b9c18447a6fb. Với số đó, sử dụng mã như thế này [0x2df0777ca228b9c18447a6fb//3**i%3 for i in range(64)]để có được số nguyên của bạn theo đúng thứ tự.
Sherlock9

Ah, trong Python 2, [0x2df0777ca228b9c18447a6fb/3**i%3for i in range(64)]có thể tốt hơn.
Sherlock9

Cảm ơn @ Sherlock9 là người mới chơi golf, bạn có thể giải thích cách thay đổi mã cơ sở này (tôi giả sử) không?
Aaron

1
Phần thứ hai là lấy lại mảng của bạn từ số đó 0x2df0777ca228b9c18447a6fb. Cái này đơn giản. Đối với một ví dụ đơn giản hơn, để lấy 0chữ số thứ từ 01221100, chỉ cần chia 3 0lần, sau đó lấy chữ số cuối cùng (sử dụng mod 3) để lấy 0. Để lấy chữ số thứ 2, chia cho 3 2lần, sau đó mod 3 để lấy 1. Việc hiểu danh sách chỉ cần chia 3 64lần để lấy lại toàn bộ mảng của bạn. Nếu bạn có thêm câu hỏi nào, chúng tôi có thể thảo luận chúng trong cuộc trò chuyện 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()}

Lưu dưới dạng tệp png. Được thụt lề, với các nguồn cấp dữ liệu:

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

Một số giải thích:

Đây là ma trận đang được vẽ (0 đại diện cho ánh sáng, 1 màu xanh đậm và 2 màu đen; ma trận bị nghiêng vì các cột là trục y và hàng trục 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

Mỗi lệnh gọi imagevẽ đồ thị ma trận đó (với mỗi số nguyên tương ứng với một màu). Với N = 4, ở đây là L (ma trận bố cục, mỗi số duy nhất đại diện cho một ô duy nhất), w (chiều rộng của các cột ma trận) và h (chiều cao của các hàng ma trận):

> 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.