Экспоненциально слизистое программирование: укладка Minecraft Slimes


108

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

Слизь 64x64

8x8 слизь ← Правда 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 ( 8x8 слизь), генерируются с помощью повышающей дискретизации ближайшего соседа (т.е. просто удваивая все пиксели). Обратите внимание, что вы должны использовать точный дизайн слизи и цвета, приведенные здесь.

Окончательное изображение будет содержать 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 должно работать так же хорошо», но ваша ошибка, похоже, выдает Out of Memory / index уже при n = 9. Это только онлайн-интерпретатор или это также происходит в автономной версии?
Дэвид Малдер

1
@DavidMulder Я тестировал в автономном режиме (компилятор, работающий на Matlab R2015b, Windows 7 64 бит, 4 ГБ ОЗУ) для ввода до 11и он работает. В 11результате получается изображение 8192 × 16376. Ибо 12это будет 16384 × 32760 (536 мегапикселей), что потребует более 4 ГБ ОЗУ, что больше, чем может выдержать мой ноутбук.
Луис Мендо

2
Мне нравится, как код начинается со смайлика, который сдерживает его слезы из-за сильных эмоций, которые этот код заставляет его чувствовать: "')
Том Дудлер

14

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

Ungolfed 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. Изображение исправлено.
имя пользователя здесь

@Giles - цените ваш комментарий, и в SO это было бы совершенно уместно, но здесь мы не меняем чужие программы - мы сообщаем им в комментариях.
Не то, что Чарльз

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 на стандартный вывод.


1
По какой-то причине ответы С довольно на мой взгляд элегантны.
downrep_nation

7

Mathematica, 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 ( Image) перед изменением размера, а затем обратно в array ( 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, #}] &

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находится массив. Таким образом, если вы сохраняете начальную сетку 8x8 в переменной x, а затем делаете это x=#&@@{##&@@{#,#}&//@x}после каждого использования, вы можете легко сгенерировать последующие плитки.
Мартин Эндер

Ой, это на 4 байта длиннее, чем нужно:#&[##&[#,#]&//@x]
Мартин Эндер

Хм, я не получаю эту работу, но вы можете сохранить некоторые больше, а) с использованием ##~Join~2и б) , 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)]чтобы получить целые числа в правильном порядке.
Sherlock9

Ах, в Python 2, [0x2df0777ca228b9c18447a6fb/3**i%3for i in range(64)]может быть лучше.
Sherlock9

Благодаря @ Sherlock9, новичку в гольфе, не могли бы вы объяснить, как работает это (я полагаю) изменение базового кода?
Аарон

1
Вторая часть - вернуть ваш массив из этого числа 0x2df0777ca228b9c18447a6fb. Это просто В более простом примере, чтобы получить 0th-у цифру 01221100, просто разделите на 3 0раза, а затем возьмите последнюю цифру (используя мод 3), чтобы получить 0. Чтобы взять 2-ую цифру, разделите на 3 2раза, затем мод 3, чтобы получить 1. Понимание списка просто делится в 3 64раза, чтобы вернуть весь ваш массив. Если у вас есть еще вопросы, мы можем обсудить их в чате PPCG .
Sherlock9

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.