Вбити його вогнем


30

Відмова: Історія, розказана в цьому питанні, є повністю вигаданою та придумана виключно для того, щоб забезпечити вступ.

Я злий фермер, і щоб подорожчати пшеницю в своєму районі, я вирішив спалити поля всіх фермерів навколо мене. Мені б дуже хотілося, щоб поля горіли полум’ям (тому я можу використовувати мій злий сміх і потирати руки разом з радістю), але я також не хочу, щоб мене спіймали спостерігати, тому мені потрібно, щоб ти змоделював поле спалюється для мене.

Ваше завдання:

Напишіть програму або функцію, яка приймає поле введення, і повертає етапи його спалювання, поки все поле не попелясте. Конкретний розділ поля, що горить, представлений цілим числом, що представляє інтенсивність полум'я. Пожежа починається з "1" і переходить до "2", а потім "3" тощо. Як тільки пожежа досягає "4", вона ловить будь-які безпосередньо (а не по діагоналі) сусідні ділянки, легкозаймисті. Як тільки вона досягне "8", вона згоряє на наступній ітерації та перетворюється на попіл, представлений символом "А". Коли місцевість ще не торкнулася вогнем, вона представляється символом "0". Наприклад, якщо поле виглядає так:

100
000

Ваша програма повинна вивести це:

100
000

200
000

300
000

410
100

520
200

630
300

741
410

852
520

A63
630

A74
741

A85
852

AA6
A63

AA7
A74

AA8
A85

AAA
AA6

AAA
AA7

AAA
AA8

AAA
AAA

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

Вхід:

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

Вихід:

Поле в кожній ітерації під час запису - або як масив, або як рядок, обмежений деяким символом.

Випробування:

0301
000A
555
 |
 v
0301
000A
555

1412
010A
666

2523
020A
777

3634
030A
888

4745
141A
AAA

5856
252A
AAA

6A67
363A
AAA

7A78
474A
AAA

8A8A
585A
AAA

AAAA
6A6A
AAA

AAAA
7A7A
AAA

AAAA
8A8A
AAA

AAAA
AAAA
AAA

Оцінка:

Це , найнижчий бал у виграшах байтів!


1
На скільки може змінюватися форма? Чи не прямокутні деталі завжди "дірки" на правому краю, або в полі можуть бути пробіли?
PurkkaKoodari

3
Тож щось, що потрапляє у 4, запускає вогонь у сусідніх квадратах, але щось, що починається у 4 чи вище, не так? Це не дуже реально.
laszlok

14
"Відмова від відповідальності: історія, розказана в рамках цього питання, є повністю вигаданою і придумана виключно для того, щоб забезпечити вступ". -> Починається з "Я злий фермер [який хоче робити злі речі]". Дуже розумний. Зараз ніхто не буде відносити до вас палаючі поля .
J_F_B_M

3
Чи можливо для початкової золи розділити поле надвоє, щоб частина його ніколи не згоріла?
aschepler

9
Якщо вогонь, що не поширюється вище 4, занадто засмучує, уявіть, що 1-4 - пожежа набуває інтенсивності, а 5-А являє собою вигорання.
Джеремі Вейріх

Відповіді:


1

APL (Діалог) , 52 байти *

Припускає, ⎕IO←0що за умовчанням для багатьох систем. Займає поле, використовуючи 0 для порожніх прорізів, 1 для незапалюваного поля, 2 для нового вогню, 5 для розповсюдження вогню та 10 для золи. Введення має бути не менше 3 × 3, що не є проблемою, оскільки додаткові рядки та стовпці можуть бути зафіксовані нулями (пробіли у форматі ОП).

{}{1=c4r←,⍵:1+4r/⍨9⍴⍳210cc}⌺3 3⍣{⍺≡⎕←⍵}

Спробуйте в Інтернеті!

Мій формат ускладнює перевірку правильності, тому ось версія з доданими до- та післяобробкою для перекладу з та у формат ОП.

⍣{} Повторюйте до:

 наступне покоління

 тотожне

⎕←⍵ поточне покоління, вихід

{}⌺3 3 Замініть кожну клітинку результатом цієї функції, застосованої до сусідства Мура:

 ,⍵ згорнути (згладити) аргумент; дає список дев'яти елементів

r← призначити на r

4⊃ підберіть четвертий елемент; центр, тобто вихідне значення комірки

c← призначити c

1= це дорівнює тому?

: якщо так, то:

  ⍳2 спочатку до teg номери; 0 1

  9⍴r ешап до довжини дев'ять; 0 1 0 1 0 1 0 1 0

  r/⍨ використовуйте це для фільтрації r (це отримує лише ортогональних сусідів)

  4∊ чотири члена цього? (тобто буде п'ять у наступному поколінні?)

  1+ додати одну; 1 якщо не загорівся, або 2, якщо не загорівся

 інше (тобто поточне значення дорівнює 0 або ≥ 2)

  ×c ознака c

  c+c плюс що (тобто збільшити на одиницю, якщо у вогні)

  10⌊ мінімум десять і це (оскільки попіл не горить на)


* У Dyalog Classic, використовуючи ⎕U233A замість .


Невеликий, але не стосується змін дошки. Приклеїли до 3х3.
Suamere

@Suamere Що? Дошка не змінює розмір, чи не так?
Адама

Вибачте, мені було не ясно. Ваша відповідь приголомшлива, але я розумію, що рішення повинно передбачати дошку змінного розміру, яка може мати або не мати прогалини "праворуч". Прогалини в середині не потрібно обробляти. "Справа", мабуть, означає, що дошка розміром 15 буде побудована як 4x4, за винятком того, що в правій нижній частині немає. І дошка розміром 8 була б побудована як розмір 3х3, за винятком того, що в правій нижній частині відсутній і т.д. Ваша відповідь наразі найкоротша, але працює лише з 3x3.
Суамер

@Suamere OP чітко вказує, що вхід 2D. Я приймаю введення як числову матрицю і дозволяю "порожні" слоти в будь-якому місці у вигляді нулів. Хоча я вимагаю, щоб вхід був не менше 3 × 3 ( ОП це дозволено ), я приймаю введення будь-якого більшого розміру. Насправді, якщо ви натиснете посилання тут , ви побачите, що мій другий приклад - 2 × 3 з нижньою правою коміркою.
Adám

Готча. Не впевнений чому, але посилання "Спробуйте тут" має проблеми (напевно, я винна), хоча ваше нове відформатоване посилання працює добре. EG: fire '0A000\n0A0A0\n0A0A0\n000A1'ідеально працює на форматованому, але я не можу отримати еквівалент роботі з першим посиланням. Я, мабуть, щось неправильно роблю. Це не працює для мене:f ↑(0 0 0)(0 1 0)(0 0 0)
Suamere

15

Пітон 3 , 232 байти

def f(j):
 k=[[int(min(9,j[x][y]+(j[x][y]>0)or 3in(lambda k,x,y:[k[i][j]for i,j in[[x-1,y],[x+1,y],[x,y-1],[x,y+1]]if(-1<i<len(k))and(-1<j<len(k[i]))])(j,x,y)))for y in range(len(j[x]))]for x in range(len(j))]
 if k!=j:print(k);f(k)

Спробуйте в Інтернеті!

-3 байти, завдяки офіаляімму, об’єднання інших лямбда в f(виглядає безладним, але економить байти, і це все, що нас хвилює)
-8 байтів завдяки містеру Кседер
-26 байтів завдяки овс
-6 байтів завдяки ppperry


Як додати порожнє місце, як у прикладі?
tuskiomi

10

JavaScript (ES6), 217 210 207 204 193 192 190 байт

Збережено 2 байти завдяки пропозиції @ Shaggy використовувати 9як A.

f=F=>[F,...(t=[],y=0,g=x=>(r=F[y])?(x||(t[y]=[]),r[x]+1)?(t[y][x]=r[x]<8?r[x]+(r[x]>0|[r[x-1],r[x+1],F[y-1]&&F[y-1][x],F[y+1]&&F[y+1][x]].includes(3)):9,g(x+1)):g(0,y++):t)(0)+""!=F?f(t):[]]

// test code
test=s=>{
  var test = document.querySelector("#in").value.split`\n`.map(e => Array.from(e).map(e => parseInt(e)));
  var out = f(test);
  document.querySelector("#out").innerHTML = out.map(e => e.map(e => e.join``).join`\n`).join`\n\n`;
};window.addEventListener("load",test);
<textarea id="in" oninput="test()">0301&#10;0009&#10;555</textarea><pre id="out"></pre>

Використовує 9замість A. Введіть як 2D масив цілих чисел. Виводимо як масив таких масивів.


Чи можете ви зберегти що-небудь за допомогою, 9а не A?
Кудлатий

7

Моделювання світу (в Emoji) , 1407 байт?

Ви не любите використовувати досліджуване пояснення як мову програмування? Недоліком цього є те, що зазвичай не дуже чітко визначена програма, тому в цьому випадку я використовую JSON, який вона експортує. (якщо у вас є якісь кращі ідеї, дайте мені знати)

{"meta":{"description":"","draw":1,"fps":1,"play":true},"states":[{"id":0,"icon":"0","name":"","actions":[{"sign":">=","num":1,"stateID":"4","actions":[{"stateID":"1","type":"go_to_state"}],"type":"if_neighbor"}],"description":""},{"id":1,"icon":"1","name":"","description":"","actions":[{"stateID":"2","type":"go_to_state"}]},{"id":2,"icon":"2","name":"","description":"","actions":[{"stateID":"3","type":"go_to_state"}]},{"id":3,"icon":"3","name":"","description":"","actions":[{"stateID":"4","type":"go_to_state"}]},{"id":4,"icon":"4","name":"","description":"","actions":[{"stateID":"5","type":"go_to_state"}]},{"id":5,"icon":"5","name":"","description":"","actions":[{"stateID":"6","type":"go_to_state"}]},{"id":6,"icon":"6","name":"","description":"","actions":[{"stateID":"7","type":"go_to_state"}]},{"id":7,"icon":"7","name":"","description":"","actions":[{"stateID":"8","type":"go_to_state"}]},{"id":8,"icon":"8","name":"","description":"","actions":[{"stateID":"9","type":"go_to_state"}]},{"id":9,"icon":"A","name":"","description":"","actions":[]}],"world":{"update":"simultaneous","neighborhood":"neumann","proportions":[{"stateID":0,"parts":100},{"stateID":1,"parts":0},{"stateID":2,"parts":0},{"stateID":3,"parts":0},{"stateID":4,"parts":0},{"stateID":5,"parts":0},{"stateID":6,"parts":0},{"stateID":7,"parts":0},{"stateID":8,"parts":0},{"stateID":9,"parts":0}],"size":{"width":9,"height":9}}}

Спробуйте тут або тут:

<iframe width="100%" height="450" src="http://ncase.me/simulating/model/?remote=-Kr2X939XcFwKAunEaMK" frameborder="0"></iframe>


6

Сітківка , 103 96 88 байт

^
¶
;{:`

T`0d`d
(?<=¶(.)*)0(?=4|.*¶(?<-1>.)*(?(1)_)4|(?<=40|¶(?(1)_)(?<-1>.)*4.*¶.*))
1

Спробуйте в Інтернеті! Використання 9золи; це можна змінити вартістю 4 байти за допомогою T`1-8`2-8A. Редагувати: Збережено 6 байт завдяки @MartinEnder. Пояснення:

^
¶

Додайте роздільник, щоб виходи не стикалися один з одним. (Також допомагає при відповідності нижче.)

;{:`

Не друкуйте остаточний стан (такий же, як попередній стан, який вже був надрукований). Повторюйте, поки пропуск не змінить стан. Роздрукуйте поточний стан перед кожним проходом.

T`0d`d

Заздалегідь інтенсивність усього пожежі.

(?<=¶(.)*)0(?=4|.*¶(?<-1>.)*(?(1)_)4|(?<=40|¶(?(1)_)(?<-1>.)*4.*¶.*))
1

Світлі не освітлені поля, якщо це доречно. Пояснення:

(?<=¶(.)*)

Виміряйте номер стовпця цього неосвітленого поля.

0

Збігайте не освітлене поле.

(?=4

Шукайте відповідне поле праворуч.

  |.*¶(?<-1>.)*(?(1)_)4

Шукайте відповідне поле в тому ж стовпці (використовуючи балансуючу групу) у рядку нижче. Зауважте, що якщо введення можна гарантувати прямокутним, то це може бути спрощено до |.*¶(?>(?<-1>.)*)4економії 3 байтів.

  |(?<=40

Шукайте відповідне поле зліва. (Оскільки ми дивимося з правого боку поля, ми також бачимо не освітлене поле.)

      |¶(?(1)_)(?<-1>.)*4.*¶.*))

Шукайте відповідне поле у ​​тому ж стовпці у рядку, що вгорі. Оскільки це перегляд і тому відповідність праворуч-ліворуч, умова балансуючої групи має з’являтися перед стовпцями, які були зіставлені балансуючою групою.


5

Perl 5 , 365 байт

@a=map{[/./g]}<>;do{say@$_ for@a;say;my@n=();for$r(0..$#a){$l=$#{$a[$r]};for(0..$l){$t=$a[$r][$_];$n[$r][$_]=($q=$n[$r][$_])>$t?$q:$t==9?9:$t?++$t:0;if($t==4){$n[$r-1][$_]||=1if$r&&$_<$#{$a[$r-1]};$n[$r+1][$_]||=1if$r<$#a&&$_<$#{$a[$r+1]};$n[$r][$_-1]||=1if$_;$n[$r][$_+1]||=1if$_<$l}}}$d=0;for$r(0..$#a){$d||=$a[$r][$_]!=$n[$r++][$_]for 0..$#{$a[$r]}}@a=@n}while$d

Спробуйте в Інтернеті!

Використовує "9" замість "A", щоб вказати спалене місце.

Пояснив

@a=map{[/./g]}<>;   # split input into a 2-D array

do{
say@$_ for@a;say;   # output the current state
my@n=();            # holds the next iteration as it's created
for$r(0..$#a){      # loop through rows
  $l=$#{$a[$r]};    # holder for the length of this row
  for(0..$l){
    $t=$a[$r][$_];  # temporary holder for current value
    $n[$r][$_]=($q=$n[$r][$_])>$t?$q:$t==9?9:$t?++$t:0; #update next iteration
    if($t==4){      # ignite the surrounding area if appropriate
      $n[$r-1][$_]||=1if$r&&$_<$#{$a[$r-1]};
      $n[$r+1][$_]||=1if$r<$#a&&$_<$#{$a[$r+1]};
      $n[$r][$_-1]||=1if$_;
      $n[$r][$_+1]||=1if$_<$l
    }
  }
}
$d=0;              # determine if this generation is different than the previous
for$r(0..$#a){$d||=$a[$r][$_]!=$n[$r++][$_]for 0..$#{$a[$r]}}
@a=@n              # replace master with new generation
}while$d

4

Haskell , 162 байти

import Data.List
i x|x<'9'=succ x|1<2=x
f('3':'@':r)="30"++f r
f(x:r)=x:f r
f e=e
a%b=a.b.a.b
g=map(i<$>).(transpose%map(reverse%f))
h x|y<-g x,y/=x=x:h y|1<3=[x]

Спробуйте в Інтернеті! Використання: hприймає поле як список рядків і повертає список полів. Незгоріле поле позначається цифрою @та попелом 9, різні вогні - це цифри1 до 8.

  • f керує розповсюдженням вогню зліва направо, замінюючи все незапалене @ поля, які мають право на палаюче 3поле0 .
  • i з кроком кожної цифри до тих пір, поки вона не перевищує 9 .
  • gзастосовується fдо кожного рядка, потім повертає рядок, застосовуєтьсяf знову і повертається назад. Потім перекладається список рядків і знову по кожному рядку та його зворотному напрямкуf .
  • hзастосовується gдо введення, поки він більше не змінюється і не збирає результати.

Помилка введення "" @ 3 @ 1 \ n @@@ 9 \ n555 @@@@@@@@@@@@@@@@@@@ ", оскільки чомусь довга лінія @s переходить на у верхньому рядку після першої ітерації Закріплення , що було б здорово, спасибі.!
Грифон - відновимо Моніка

@Gryphon Зсув спричинений перенесенням матриці символів. Він працює, якщо інші рядки дорівнюють однаковій довжині з деяким символом, який не є ні полем, ні вогнем, ні золом, наприклад _. Якщо це не прийнятно, я боюся, що мені доведеться видалити відповідь, оскільки він зосереджений на використанні, transposeі я не бачу способу легко виправити це, не вводячи тонни байтів.
Лайконі

4

C (gcc) , 308 305 299 297 295 291 байт

#define F B[i][v]
m(A,B,k,y,m,U,i,v)char**B;{do{for(i=k=y=0;i<A;puts(""),++i)for(v=0;v<(m=strlen(B[i]));F=(U=F)>48&&F<56?F+1:F>55?65:(i+1<A&&B[i+1][v]==51||v+1<m&&B[i][v+1]==51||v-1>-1&&B[i][v-1]==52||i-1>-1&&B[i-1][v]==52)&&U<49?49:F,putchar(U),k+=U<49||U>64,++y,++v);puts("");}while(k-y);}

Ця програма визначає функцію, яка займає два входи, вказівник на масив рядків, що передує його довжині, як це дозволено цим замовчуванням вводу / виводу. Виводить STDOUT за допомогою зворотного нового рядка.

Спробуйте в Інтернеті!


Працює назавжди на вході 80.
aschepler

@aschepler Вибачте! Я припускав, що всі персонажі повинні перетворитись на As, але, мабуть, я вважав неправильним. У будь-якому випадку, дякую за інформацію. Це зараз виправлено.
Р. Кап


@GiacomoGarabello Не можу повірити, що забув про цю тактику. Дякуємо, що нагадали! :)
Р. Кап

4

Октава, 72 69 байт

a=input(''),do++a(a&a<9);a+=imdilate(a==4,~(z=-1:1)|~z')&~a,until a>8

Вхід приймається як двовимірний масив чисел та порожні місця, позначені символом Inf. 'A'було замінено на 9. Проміжні результати (як масив чисел) друкуються неявно.

Спробуйте в Інтернеті!

Пояснення:

У циклі функція imdilate(морфологічне розширення зображення) з пакету зображень використовується для імітації поширення вогню.


1
Це працює з дошками будь-яких розмірів і навіть з купою отворів. EG: [0 Inf 0 0 0;0 Inf 0 Inf 0;0 Inf 0 Inf 0;0 0 0 Inf 1]- Дуже добре
Suamere

1

Пітон 2 , 325 байт

def f(x):
 while{i for m in x for i in m}>{9,''}:
    yield x;i=0
    for l in x:
     j=0
     for c in l:
        if 0<c<9:x[i][j]+=1
        j+=1
     i+=1
    i=0
    for l in x:
     j=0
     for c in l:
        if c==0 and{1}&{x[k[1]][k[2]]==4for k in[y for y in[[i,i-1,j],[i<len(x)-1,i+1,j],[j,i,j-1],[j<len(l)-1,i,j+1]]if y[0]]}:x[i][j]+=1
        j+=1
     i+=1
 yield x

fприймає вхід як двовимірний масив цілих чисел та порожні місця, позначені знаком ''. 'A'було замінено на9 . Функція виводить генератор усіх полів у часі в одному форматі.

Спробуйте в Інтернеті!


1

Октава , 212 байт

function r(f)b=48;f-=b;c=-16;l=f~=-c;d=17;p=@(x)disp(char(x+b));g=@()disp(' ');p(f);g();while~all(any(f(:)==[0 d c],2))m=f>0&l;f(m)+=1;k=conv2(f==4,[0 1 0;1 0 1;0 1 0],'same')&~m&l;f(k)+=1;f(f>8&l)=d;p(f);g();end

Для запуску задайте масив символів, наприклад:

f = ['0301','000A','555 '];

... тоді робіть:

r(f)

Пояснення коду для наступного ...

Спробуйте в Інтернеті!

Примітка. Я намагався запустити цей код за допомогою tio.run , але не отримав жодного результату. Довелося скористатися іншою послугою.


Дійсно саме в той момент, коли я хочу опублікувати
октавну

1

PHP, 226 212 210 209 185 177 байт

for($f=file(m);$f!=$g;print"
")for($g=$f,$y=0;$r=$f[$y++];)for($x=-1;~$c=$r[++$x];$f[$y-1][$x]=$c=="0"?strstr($g[$y-2][$x].$r[$x-1].$f[$y][$x].$r[$x+1],51)/3:min(++$c,9))echo$c;

приймає вхід з останнього рядка з імені файлу m;9для попелу.

Запустіть -nrабо спробуйте в Інтернеті .


перший підхід: PHP 7.0, 209 байт

for($f=$g=file(m);trim(join($f),"A
");print"
".join($f=$g))for($y=-1;(a&$c=$r[++$x])||$r=$f[$y-=$x=-1];)for(+$c&&$g[$y][$x]=++$c<9?$c:A,$a=4;$a--;$q=$p)$c-4|($w=&$g[$y+$p=[1,0,-1][$a]])[$q+=$x]!="0"||$w[$q]=1;

приймає вхід із заздалегідь нового рядка з імені файлу m .

Запустіть -nrабо спробуйте в Інтернеті .

Примітки до версії PHP (для старого підходу)

  • для PHP старше 7.0, замінити всі після того, як $c-4|з$g[$y+$p=[1,0,-1][$a]][$q+=$x]!="0"||$g[$y+$p][$q]=1;
  • для PHP старше 5,5 замінити [1,0,-1][$a]на$a%2*~-($a&2)
  • для PHP, що перевищує 7,0, замініть a&$cна ""<$c, +$cз 0<$cі $c-4на$c!=4

не працює для інших тестових випадків ... sandbox.onlinephpfunctions.com/code/…
g19fanatic

@ g19fanatic нерухомий та гольф. дякую за те, що помітили.
Тит

0

Октава, 419 312 байт

M=input('') %take a matrix M as input
[a, b]=size(M); %size M for later
while mean(mean(M))!=9 %while the whole matrix M isn't ashes
M=M+round(M.^0.001); %if there is a nonzero int add 1 to it
for i=1:a %loop over all values of M
for j=1:b
if(M(i,j)==4) %if a value of 4 is found, ignite the zeros around it
if(M(max(i-1,1),j)==0) M(i-1,j)++;end
if(M(min(i+1,a),j)==0) M(i+1,j)++;end
if(M(i,max(j-1,1))==0) M(i,j-1)++;end      
if(M(i,min(j+1,b))==0) M(i,j+1)++;end
elseif(M(i,j)==10) M(i,j)--;
end
end
end
M %display the matrix
end

Спробуйте в Інтернеті!

Це моя версія, вона працює, тому зараз мені ще потрібно пограти в неї. Я думаю, що це може бути набагато коротше, якщо я знайду спосіб знайти індекси 4 у матриці, але не знаю як.
PS: А - це 9 у моєму коді.


2
Замість endif endforі endwhileможете писатиend
rahnema1

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