Matá-lo com fogo

30

Isenção de responsabilidade: a história contada nesta pergunta é totalmente fictícia e inventada apenas com o objetivo de fornecer uma introdução.

Sou um fazendeiro malvado e, para aumentar o preço do trigo na minha região, decidi queimar os campos de todos os fazendeiros à minha volta. Eu realmente gostaria de ver os campos pegando fogo (para que eu possa usar minha risada maligna e esfregar minhas mãos com alegria), mas também não quero ser pego assistindo, então preciso que você simule o campo sendo incinerado para mim.

Sua tarefa:

Escreva um programa ou função que tome como entrada um campo e retorne os estágios dele até que todo o campo fique cinza. Uma seção específica do campo em chamas é representada por um número inteiro que representa a intensidade da chama. Um incêndio começa em "1" e passa para "2" e depois "3" e assim por diante. Quando o fogo atinge "4", ele captura as áreas adjacentes diretamente (não na diagonal) que são inflamáveis. Quando atinge "8", queima na próxima iteração e se transforma em cinza, representada por um "A". Quando uma área ainda não foi tocada pelo fogo, ela é representada por um "0". Por exemplo, se o campo estiver assim:

100
000

Seu programa deve gerar o seguinte:

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

Se desejar, você pode substituir os símbolos acima por qualquer conjunto de símbolos que escolher, desde que sejam consistentes e distintos um do outro.

Entrada:

A posição inicial do campo, de qualquer forma padrão, como uma sequência delimitada por linhas novas, como acima.

Saída:

O campo em cada iteração à medida que é gravado, como uma matriz ou como uma sequência delimitada por algum caractere.

Casos de teste:

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

Pontuação:

Isso é , a menor pontuação em bytes ganha!

Gryphon - Restabelecer Monica
fonte
1
Quanto a forma pode variar? As peças não retangulares sempre "furos" na borda direita ou podem haver espaços no campo?
PurkkaKoodari
3
Então, algo que atinge 4 inicia um incêndio em quadrados adjacentes, mas algo que começa com 4 ou mais, não? Isso não é muito realista.
laszlok
14
"Isenção de responsabilidade: a história contada nesta pergunta é inteiramente fictícia e inventada apenas com o objetivo de fornecer uma introdução". -> Começa com "Eu sou um fazendeiro do mal [que quer fazer coisas más]." Muito esperto. Ninguém irá relacionar os campos em chamas para você agora .
J_F_B_M 8/08
3
É possível que as cinzas iniciais separem o campo em dois, para que parte dele nunca queime?
aschepler
9
Se o fogo que não estiver se espalhando acima de 4 for muito perturbador, imagine que 1-4 seja o fogo ganhando intensidade e 5-A o represente.
Jeremy Weirich

Respostas:

1

APL (Dyalog) , 52 bytes *

Assume o ⎕IO←0padrão em muitos sistemas. Toma campo usando 0 para slots vazios, 1 para campo não queima, 2 para fogo novo, 5 para espalhar fogo e 10 para cinzas. A entrada deve ter pelo menos 3 × 3, o que não é um problema, pois linhas e colunas adicionais podem ser preenchidas com zeros (espaços no formato do OP).

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

Experimente online!

Meu formato dificulta a verificação da correção, então aqui está uma versão com pré e pós-processamento adicionados para traduzir de e para o formato do OP.

⍣{} Repita até:

 a próxima geração

 é idêntico a

⎕←⍵ a geração atual, gerada

{}⌺3 3 Substitua cada célula pelo resultado dessa função aplicada ao bairro de Moore:

 ,⍵ desviar (achatar) o argumento; fornece lista de nove elementos

r← atribuir a r

4⊃ escolha o quarto elemento; o centro, ou seja, o valor original da célula

c← atribuir a c

1= é igual a isso?

: Se sim, então:

  ⍳2 primeiro a Ɩ ntegers; 0 1

  9⍴r eshape no comprimento nove; 0 1 0 1 0 1 0 1 0

  r/⍨ use isso para filtrar r (isso obtém apenas os vizinhos ortogonais)

  4∊ quatro é um membro disso? (ou seja, haverá cinco na próxima geração?)

  1+ Adicione um; 1 se não pegou fogo ou 2 se pegou fogo

 caso contrário (ou seja, o valor atual é 0 ou ≥ 2)

  ×c o signum de c

  c+c mais que (isto é, aumentar em um se estiver pegando fogo)

  10⌊ mínimo de dez e que (como as cinzas não queimam)


* No Dyalog Classic, use em ⎕U233A vez de .

Adão
fonte
Pequeno, mas não lida com mudanças no quadro. Preso a um 3x3.
Suamere
@Suamere What? O quadro não muda de tamanho, muda?
Adám
Desculpe, eu não estava claro. Sua resposta é impressionante, mas entendo que a solução deve permitir uma placa de tamanho variável que pode ou não ter lacunas "à direita". Lacunas no meio não precisam ser tratadas. "À direita" parece significar que uma placa de tamanho 15 seria construída como um 4x4, exceto que a parte inferior mais à direita está faltando. E uma placa tamanho 8 seria construída como um 3x3, exceto que a parte inferior mais à direita está faltando etc. É assim que leio os requisitos do desafio. Sua resposta é atualmente a mais curta, mas funciona apenas com um 3x3.
Suamere 9/08/17
O @Suamere OP afirma claramente que a entrada é 2D. Pego a entrada como uma matriz numérica e permito slots "vazios" em qualquer lugar, na forma de zeros. Embora exija que a entrada seja no mínimo 3 × 3 (o OP permitiu isso ), aceito entradas de qualquer tamanho maior. De fato, se você clicar no link aqui , verá que meu segundo caso de exemplo é 2 × 3 com a célula inferior direita vazia.
Adám 9/08/17
Peguei vocês. Não sei por que, mas o link Experimente aqui tem problemas (provavelmente é minha culpa), embora seu novo link formatado funcione bem. EG: fire '0A000\n0A0A0\n0A0A0\n000A1'funciona perfeitamente no formatado, mas não consigo obter um equivalente para trabalhar com o primeiro link. Provavelmente estou fazendo algo errado. Isso não funciona para mim:f ↑(0 0 0)(0 1 0)(0 0 0)
Suamere
15

Python 3 , 232 bytes

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)

Experimente online!

-3 bytes graças ao officialaimm, mesclando o outro lambda em f(parece confuso, mas economiza bytes e é com isso que nos preocupamos)
-8 bytes graças ao Sr. Xoder
-26 bytes graças a ovs
-6 bytes graças a ppperry

HyperNeutrino
fonte
Como adiciono um espaço em branco, como no exemplo?
precisa saber é o seguinte
10

JavaScript (ES6), 217 210 207 204 193 192 190 bytes

Economizou 2 bytes graças à sugestão de @ Shaggy de usar 9como 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>

Usa em 9vez de A. Entrada como uma matriz 2D de números inteiros. Saída como uma matriz de tais matrizes.

PurkkaKoodari
fonte
Você poderia salvar alguma coisa usando em 9vez de A?
Shaggy
7

Simulando o mundo (em Emoji) , 1407 bytes?

Você não gosta de usar uma explicação explorável como linguagem de programação? A desvantagem disso é que geralmente não há um programa muito bem definido; portanto, neste caso, estou usando o JSON que ele exporta. (se você tiver alguma idéia melhor, me avise)

{"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}}}

Experimente aqui ou aqui:

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

DanTheMan
fonte
6

Retina , 103 96 88 bytes

^
¶
;{:`

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

Experimente online!Usa 9para cinzas; isso pode ser alterado a um custo de 4 bytes usando T`1-8`2-8A. Editar: salvou 6 bytes graças a @MartinEnder. Explicação:

^
¶

Adicione um separador para que as saídas não se colidam. (Também ajuda na correspondência abaixo.)

;{:`

Não imprima o estado final (que é o mesmo que o estado anterior que já foi impresso). Repita até que o passe não mude de estado. Imprima o estado atual antes de cada passagem.

T`0d`d

Avance a intensidade de todo o fogo.

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

Campos apagados claros, conforme apropriado. Sub-explicação:

(?<=¶(.)*)

Meça o número da coluna desse campo apagado.

0

Corresponder ao campo apagado.

(?=4

Procure um campo adequado à direita.

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

Procure um campo adequado na mesma coluna (usando um grupo de equilíbrio) na linha abaixo. Observe que, se a entrada puder ser garantida retangular, isso poderá ser simplificado para|.*¶(?>(?<-1>.)*)4 para uma economia de 3 bytes.

  |(?<=40

Procure um campo adequado à esquerda. (Como estamos olhando do lado direito do campo, também vemos o campo apagado.)

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

Procure um campo adequado na mesma coluna na linha acima. Como essa é uma correspondência retroativa e, portanto, da direita para a esquerda, a condição do grupo de balanceamento deve aparecer antes das colunas correspondentes ao grupo de balanceamento.

Neil
fonte
5

Perl 5 , 365 bytes

@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

Experimente online!

Usa '9' em vez de 'A' para indicar um local queimado.

Explicado

@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
Xcali
fonte
4

Haskell , 162 bytes

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]

Experimente online! Uso: hpega um campo como uma lista de linhas e retorna uma lista de campos. Um campo não queimado é indicado por @e cinza por 9, os diferentes incêndios são os dígitos 1para 8.

  • fgerencia a propagação do fogo da esquerda para a direita, substituindo todos os @campos não queimados que são adequados para um 3campo em chamas 0.
  • iincrementa cada dígito desde que seja menor que 9.
  • gaplica f- se a cada linha, depois reverte a linha, aplica f- se novamente e reverte para trás. Em seguida, a lista de linhas é transposta e novamente em cada linha e seu inverso fé aplicado.
  • haplica g- se à entrada até que ela não seja mais alterada e colete os resultados.
Laikoni
fonte
Falha na entrada "" @ 3 @ 1 \ n @@@ 9 \ n555 @@@@@@@@@@@@@@@@@@@ ", pois, por algum motivo, a longa linha de @s muda para a linha superior após a primeira iteração .. Correção que seria ótimo, obrigado!
Gryphon - Reinstate Monica
@Gryphon O deslocamento é causado pela transposição da matriz de caracteres. Funciona se as outras linhas tiverem o mesmo comprimento com algum caractere que não represente campo, fogo ou cinza, por exemplo _. Se isso não for aceitável, receio ter que excluir a resposta, porque ela está centrada no uso de transposee não vejo uma maneira de corrigi-la facilmente sem a introdução de toneladas de bytes.
Laikoni
4

C (GCC) , 308 305 299 297 295 291 bytes

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

Este programa define uma função que recebe duas entradas, um ponteiro para uma matriz de seqüências precedidas por seu comprimento, conforme permitido por este padrão de E / S. Saídas para STDOUT com uma nova linha à direita.

Experimente online!

R. Kap
fonte
É executado para sempre na entrada 80.
aschepler
@aschepler Desculpe! Eu assumi que todos os personagens deviam se transformar em As, mas aparentemente eu assumi errado. De qualquer forma, obrigado pela informação. Está consertado agora.
R. Kap
-6 bytes! Tio Link
Giacomo Garabello
@GiacomoGarabello Não acredito que me esqueci dessa tática. Obrigado por me lembrar! :)
R. Kap
4

Oitava, 72 69 bytes

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

A entrada é tomada como uma matriz 2D de números e pontos vazios marcados com Inf. 'A'foi substituído por 9. Resultados intermediários (como matriz de números) impressos implicitamente.

Experimente online!

Explicação:

Em um loop, a função imdilate(dilatação morfológica da imagem) do pacote de imagens é usada para simular a propagação do fogo.

rahnema1
fonte
1
Isso funciona com placas de todos os tamanhos e até com vários buracos. EG: [0 Inf 0 0 0;0 Inf 0 Inf 0;0 Inf 0 Inf 0;0 0 0 Inf 1]- Muito bom
Suamere
1

Python 2 , 325 bytes

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

frecebe a entrada como uma matriz 2D de números inteiros e pontos vazios marcados com ''. 'A'foi substituído por 9. A função gera um gerador de todos os campos ao longo do tempo no mesmo formato.

Experimente online!

nog642
fonte
1

Oitava , 212 bytes

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

Para executar, especifique uma matriz de caracteres como:

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

... então faça:

r(f)

Explicação do código a seguir ...

Experimente online!

Nota: Tentei executar esse código com tio.run , mas não obtive nenhuma saída. Eu tive que usar outro serviço.

rayryeng - Restabelecer Monica
fonte
Realmente apenas no momento eu quero postar uma resposta oitava você responder antes de mim ..
Michthan
1

PHP, 226 212 210 209 185 177 bytes

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;

recebe entrada com uma nova linha à direita de um arquivo chamado m; 9para cinzas.

Corra com -nrou experimente online .


primeira abordagem: PHP 7.0, 209 bytes

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;

leva de entrada com uma nova linha de fuga de um arquivo chamado m.

Corra com -nrou experimente online .

Notas da versão do PHP (para abordagem antiga)

  • para PHP anterior a 7.0, substitua tudo depois $c-4|por$g[$y+$p=[1,0,-1][$a]][$q+=$x]!="0"||$g[$y+$p][$q]=1;
  • para PHP anterior a 5.5, substitua [1,0,-1][$a]por$a%2*~-($a&2)
  • para PHP mais recente que 7.0, substitua a&$cpor ""<$c, +$cpor 0<$ce $c-4com$c!=4
Titus
fonte
não funciona' para outros casos de teste ... sandbox.onlinephpfunctions.com/code/...
g19fanatic
@ g19fanatic fixo e jogado. obrigado por perceber.
Titus
0

Oitava, 419312 bytes

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

Experimente online!

Esta é a minha versão que funciona, então agora eu ainda preciso jogar golfe. Eu acho que pode ser muito mais curto se eu encontrar uma maneira de encontrar os índices dos 4 em uma matriz, mas não sei como.
PS: A é um 9 no meu código.

Michthan
fonte
2
Em vez de endif endfore endwhilevocê pode escreverend
rahnema1
0

Estêncil (modo ) , 22 bytes

S8:'A'0::S⋄(3N)⌈S+s

Experimente online!

Assim como na entrada de teste, use números inteiros separados por espaços para 0- 8, ' 'para blank e 'A'for A. Lembre-se de adicionar espaços em branco à direita também.

Erik, o Outgolfer
fonte