Убить его огнем


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 (Dyalog) , 52 байта *

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

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

Попробуйте онлайн!

Мой формат затрудняет проверку на правильность, поэтому вот версия с добавленной предварительной и последующей обработкой для перевода из и в формат OP.

⍣{... } повторять до:

 новое поколение

 идентично

⎕←⍵ текущее поколение, выведено

{}⌺3 3 Замените каждую ячейку результатом этой функции, примененной к ее окрестности Мура:

 ,⍵ расправиться с аргументом; дает список из девяти элементов

r← назначить на г

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

c← назначить с

1= один равен этому?

: если так, то:

  ⍳2 сначала ɩ ntegers; 0 1

  9⍴г eshape к длине девять; 0 1 0 1 0 1 0 1 0

  r/⍨ используйте это, чтобы отфильтровать r (это получает только ортогональных соседей)

  4∊ четыре члена этого? (т.е. будет ли пятерка в следующем поколении?)

  1+ добавить один; 1, если не загорелся, или 2, если загорелся

 иначе (т.е. текущее значение 0 или ≥ 2)

  ×c знак c

  c+с плюс это (то есть увеличение на единицу, если в огне)

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


* В Dyalog Classic, используя ⎕U233A вместо .


Небольшой, но не касается смены доски. Застрял в 3х3.
Суамер,

@ Суамер Что? Доска не меняет размер, не так ли?
17

Извини, мне было непонятно. Ваш ответ потрясающий, но я понимаю, что решение должно предусматривать плату переменного размера, которая может иметь или не иметь пробелы «справа». Пробелы в середине не требуются для обработки. «Справа» означает, что доска размера 15 будет построена как 4х4, за исключением того, что отсутствует крайняя правая часть. И доска размера 8 будет построена как 3х3, за исключением того, что отсутствует крайний правый нижний элемент и т. Д. Вот как я читаю требования к заданию. Ваш ответ в настоящее время самый короткий, но работает только с 3х3.
Суамер,

@Suamere OP четко заявляет, что ввод 2D. Я принимаю входные данные в качестве числовой матрицы и допускаю «пустые» слоты в любом месте, в виде нулей. В то время как я требую, чтобы входное значение было минимум 3 × 3 ( OP допускал это ), я принимаю ввод любого большего размера Фактически, если вы нажмете ссылку здесь , вы увидите, что мой второй пример - 2 × 3 с пустой правой нижней ячейкой.
Адам

Попался. Не знаю почему, но у ссылки «Попробуй здесь» есть проблемы (возможно, это моя ошибка), хотя твоя новая отформатированная ссылка работает хорошо. EG: fire '0A000\n0A0A0\n0A0A0\n000A1'отлично работает на отформатированном, но я не могу получить эквивалент для работы с первой ссылкой. Я, вероятно, делаю что-то не так. Это не работает для меня:f ↑(0 0 0)(0 1 0)(0 0 0)
Suamere

15

Python 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 байта благодаря officialaimm путем слияния другой лямбды в f(выглядит грязно, но сохраняет байты, и это все, что нас волнует)
-8 байтов благодаря Mr. Xoder
-26 байтов благодаря ovs
-6 байтов благодаря ppperry


Как добавить пробел, как в примере?
tuskiomi

10

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

Сохранено 2 байта благодаря предложению @ Shaggy использовать 9as 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 . Ввод в виде двумерного массива целых чисел. Вывод в виде массива таких массивов.


Не могли бы вы сохранить что-нибудь, используя 9вместо A?
Лохматый

7

Симулирование мира (в эмодзи) , 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
Это работает с досками всех размеров и даже с кучей дырок. [0 Inf 0 0 0;0 Inf 0 Inf 0;0 Inf 0 Inf 0;0 0 0 Inf 1]
Е.Г .

1

Python 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 , но я не получил никакого вывода. Я должен был использовать другой сервис.


Действительно, в данный момент я хочу опубликовать октавный ответ, который вы отвечаете передо мной ..
Michthan

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.