Експоненціально струнке програмування: укладання шлаків Minecraft


108

Сліни - це вороги у формі куба у Minecraft, які при вбиванні розбиваються на кілька менших версій себе. Для цілей цього виклику ми зобразимо їх як зображення 8 × 8 пікселів з 3 кольорами:

64х64 слиз

8х8 слиз ← Версія 8 × 8 версія.

Точні кольори RGB:

  • 0, 0, 0 для очей і рота
  • 110, 170, 90 для центральної, темніше зеленого кольору
  • 116, 196, 96 для зовнішньої, світлішої зеленої

Виклик

Напишіть програму або функцію, яка приймає натуральне число N і виводить зображення N розмірів шлейків, упакованих у прямокутник. Переходячи зліва направо, зображення повинно відповідати шаблону:

  • Стек 2 (N-1) 8 × 8 шлейфів.
  • Стек 2 (N-2) 16 × 16 шлейфів.
  • Стек із 2 (N-3) 32 × 32 шлейфів.
  • І так далі, поки стек не містить лише одного слизу.

Образи слизу, розміри яких перевищують 8 × 8 версії ( 8х8 слиз), генеруються шляхом перегляду найближчого сусіда (тобто просто подвоєння всіх пікселів). Зверніть увагу, що ви повинні використовувати точний дизайн слизу та кольори, наведені тут.

Кінцеве зображення буде містити 2 N -1 шліца і матиме 2 (N + 3) -8 пікселів і 2 (N + 2) пікселів у висоту.

Зображення може виводитися у будь-якому загальному форматі файлу зображення, зберігатися у файлі або друкуватися / повертатися у вигляді необробленого потоку даних або безпосередньо відображатися під час виконання.

Виграє найкоротший код у байтах.

Приклади

Ваша програма повинна дати ці точні результати.

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 повинен працювати так само добре.


30
Я б підтримав, але у мене немає голосів. Я залишаю цей коментар, тому я не забуду завтра подати заяву.
NoOneIsHere

23
Я підтримую ваш коментар, тому що у мене теж закінчилися.
трихоплакс

4
"Зразки слизу, розміри яких перевищують 8 × 8 версії (), генеруються шляхом кращого супроводу (тобто подвоєння всіх пікселів)." Ви мали на увазі вчетверо всі пікселі, перетворивши кожен піксель на квадрат 2х2?
Caridorc

1
@Caridorc Подвоєння в кожному напрямку?
wizzwizz4

@ wizzwizz4 Так, кожен піксель стає 4, правильно?
Caridorc

Відповіді:


21

MATL , 77 76 74 байт

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

Код працює в цій комісії , що є раніше, ніж виклик.

Ви можете спробувати його в мережі MATL . Цей перекладач досі експериментальний. Якщо це не працює, спробуйте оновити сторінку та натисніть «Виконати» ще раз.

Ось приклад запуску в офлайн-перекладачі:

введіть тут опис зображення

Пояснення

:                     % 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 повинен працювати так само добре.", Але ваш, здається, видає помилки з пам'яті / індексу вже при n = 9. Це лише онлайн-інтерпретатор, чи це також відбувається в офлайн-версії?
Девід Малдер

1
@DavidMulder Я перевірив офлайн (компілятор працює на Matlab R2015b, Windows 7 64 біт, 4 ГБ оперативної пам’яті) на введення до, 11і він працює. Для отримання 11результату є 8192 × 16376 зображень. Бо 12це було б 16384 × 32760 (536 мегапікселів), для цього потрібно більше 4 ГБ оперативної пам’яті, що більше, ніж мій ноутбук.
Луїс Мендо

2
Мені подобається, як код починається з посмішки, який стримує сльози через сильні емоції, які цей код змушує його відчувати: "")
Том Додлер

14

Діалог APL, 118 113 байт

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

припускаючи ⎕IO=0

Справа наліво:

i←2*⍳⎕ повноваження 1 2 4 ... 2 н-1

i{ }¨⌽iповторення повноважень (з ) та зворотних повноважень ( )

⊤¨⍨⊂32⍴3 декодуйте кожне з чисел зліва як 32 потрійні цифри

8 8⍴∊ вирівняти та переробити до 8 × 8

⍺⌿⍺/повторити кожен рядок і стовпець разів

⍵⍴⊂робити копії

⊃⍪/ і укладайте їх вертикально

⊃,/ приєднати всі результати горизонтально

3↑(116 196 96)(110 170 90)кольори; 3↑розширює їх с(0 0 0)

[ ]індексувати кольори з кожним елементом матриці; Результатом є матриця RGB

('P3',⌽∘⍴,255,∊)є "поїзд" - функція, яка повертається з 'P3'наступною зворотною формою аргументу 255, і аргумент сплющений.


Я думаю, ви можете написати програму, припускаючи, ⎕IO←0і просто вказати її як умову, поза кількістю байтів. Багато систем APL використовують це як за замовчуванням. (У тому числі ваш LOL)
Tobia

11

JavaScript (ES7), 326 327 байт

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

Версія без вогнів ES6

Спробуйте самі.

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

Єдина відмінність між версією ES7 та ES6 - це використання **замість Math.pow(). Ви також можете бачити, як можна викликати функцію - у цьому прикладі з n=4.

Результат

введіть тут опис зображення


Правки

  • збережено 1 байт - знайдено непотрібну крапку з комою;

Це досить повільно і може зайняти деякий час, щоб число, що перевищує 10.


2
кольори здаються трохи відключеними на зображенні тут. Ви, можливо, знімали знімок із вбудованим f.lux?
Джеззамон

@Jezzamon Дякую, що вказав на це - я теж помітив це. Існує невелика ймовірність, що я міг обрати " Перетворити кольори документа в робочий простір " під час імпорту екрана в Photoshop. Зображення виправлено зараз.
insertusernamehere

@Giles - високо оцінюйте ваш коментар, і в ТА це було б цілком доречно, але тут ми не змінюємо чужих програм - ми повідомляємо їх у коментарях.
Не те, що Чарльз

7

C, 220 байт

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

Я додав непотрібні нові рядки для читабельності, оцінка є без цих нових рядків.

Визначає функцію, f(n)яка виводить звичайне зображення PPM у stdout.


1
Чомусь відповіді на С є досить елегантними на мою думку.
downrep_nation

7

Математика, 267 255 254 225 212 байт

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 байти завдяки Мартіну Ендеру

Пропозиції з гольфу вітаються, особливо для побудови масиву 8 на 8 (на 3) s. На жаль, немає " ArrayResize" аналога для ImageResize, тому масив потрібно перетворити у зображення ( Image) перед зміною розміру, а потім повернути в масив ( ImageData), щоб зробити Joining.

Безголовки:

(* 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. Для sйого генерування може бути коротше кодування значень пікселів як базове число 3, але я повинен спробувати бути впевненим. У той же час, ви можете зберегти байти не визначаючи що b, g, f, e, tпоки вони вам не потрібні, і sне потрібно ім'я на всіх і ні робить c. Для 2^(j-1)8можна використовувати 4*2^j. Застосовуючи все це, я закінчую 225 байт: pastebin.com/YnkUwvwV
Мартін Ендер

@MartinEnder Велика подяка, все це дуже хороші пропозиції! (Зауважте, що самостійно: уникайте називати речі, якщо це можливо, інакше виконайте завдання за (а не раніше) першого події.)
lastresort

У мене немає часу , щоб зрозуміти це повністю прямо зараз, але ось ідея , щоб уникнути Image, ImageResize, ImageDataречі. Цей біт підірває масив в 2 рази: #&@@{##&@@{#,#}&//@x}де xзнаходиться масив. Отже, якщо ви зберігаєте початкову сітку 8х8 у змінній x, а потім робите x=#&@@{##&@@{#,#}&//@x}після кожного використання, ви можете генерувати послідовні плитки досить легко.
Мартін Ендер

Ну, це на 4 байти довше, ніж потрібно:#&[##&[#,#]&//@x]
Мартін Ендер

Гм, я ще не працюю над цим, але ви можете зберегти ще декілька за допомогою a) за допомогою ##~Join~2і b), f={g,a=##&[G,G,G],a,g}а потім замінити кожне подальше виникненняG,G,G з aа.
Мартін Ендер

4

Python 2.7: 424 412 405 376 357 байт

Я трохи новачок у гольфі .... тут ми йдемо

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

неозорий і перевірений по довжині ..

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]на користь raw_input()збереження додаткової заяви про імпорт

edit2: скорочений імпорт PIL: видалено from ImageдоданоPIL.

edit3: Дякую @ Sherlock9 за шістнадцятковий кодування шаблону слизу

edit4: не потрібна функція def та використовується input() замістьraw_input()


будь-які пропозиції більш ніж вітаються :) особливо для зменшення масиву шаблонів
Аарон

Щось на зразок використання '0000100001111110111211100111111102211220022112200111111000001000'(ваш масив назад) перетворено з бази 3 в базу 16 0x2df0777ca228b9c18447a6fb. З цим номером використовуйте такий код, щоб [0x2df0777ca228b9c18447a6fb//3**i%3 for i in range(64)]встановити цілі числа у правильному порядку.
Шерлок9

Ах, в Python 2, [0x2df0777ca228b9c18447a6fb/3**i%3for i in range(64)]можливо, буде і краще.
Шерлок9

Дякуючи @ Sherlock9, що є новим у гольфі, ви могли б пояснити, як працює ця (я припускаю) зміна базового коду?
Аарон

1
Друга частина - повернути масив з цього числа 0x2df0777ca228b9c18447a6fb. Це просто. Для більш простого прикладу, щоб отримати цю 0цифру 01221100, просто розділіть на 3 0рази, а потім візьміть останню цифру (використовуючи мод 3), щоб отримати 0. Щоб взяти другу цифру, розділіть на 3 2рази, а потім мод 3, щоб отримати 1. Розуміння списку просто ділиться на 3 64рази, щоб отримати повний масив. Якщо у вас є якісь питання, ми можемо обговорити їх у чаті PPCG .
Шерлок9

1

R, 378 356 346 334 байт

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

Зберігається як png-файл. Відступ, із стрічковими каналами:

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

Деякі пояснення:

Ось матриця, яка будується (0 представляють світлозелений, 1 темнозелений та 2 чорний; матриця нахилена, оскільки стовпці - це вісь y, а рядки - вісь 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

Кожен виклик imageпобудувати графік цієї матриці (з кожним цілим числом, відповідним кольору). Для N = 4 тут L (матриця компонування, кожне унікальне число являє собою один єдиний графік), w (ширини матричних стовпців) і h (висоти рядків матриці):

> 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.