Mátalo con fuego


30

Descargo de responsabilidad: La historia contada dentro de esta pregunta es completamente ficticia e inventada únicamente con el propósito de proporcionar una introducción.

Soy un granjero malvado, y para aumentar el precio del trigo en mi área, he decidido quemar los campos de todos los granjeros que me rodean. Realmente me gustaría ver que los campos se incendiaran (para poder usar mi risa malvada y frotar mis manos con alegría), pero tampoco quiero que me atrapen observando, así que necesito que simules que el campo está siendo incinerado por mi

Tu tarea:

Escriba un programa o función que tome como entrada un campo y devuelva las etapas de grabación hasta que todo el campo sea ceniza. Una sección específica del campo que está en llamas está representada por un número entero que representa la intensidad de la llama. Un incendio comienza en "1" y pasa a "2" y luego a "3", y así sucesivamente. Una vez que el fuego alcanza "4", atrapa cualquier área adyacente directa (no diagonal) que sea inflamable en el fuego. Una vez que alcanza "8", se quema en la siguiente iteración y se convierte en ceniza, representada por una "A". Cuando un área aún no ha sido tocada por el fuego, se representa con un "0". Por ejemplo, si el campo se ve así:

100
000

Su programa debería generar esto:

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

Si lo desea, puede reemplazar los símbolos anteriores con cualquier conjunto de símbolos que elija, siempre que sean consistentes y distintos entre sí.

Entrada:

La posición inicial del campo, en cualquier forma estándar, como una cadena delimitada con una nueva línea como se indicó anteriormente.

Salida:

El campo en cada iteración a medida que se quema, ya sea como una matriz o como una cadena delimitada por algún carácter.

Casos de prueba:

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

Tanteo:

Este es el , ¡el puntaje más bajo en bytes gana!


1
¿Cuánto puede variar la forma? ¿Las partes no rectangulares son siempre "agujeros" en el borde derecho, o puede haber espacios en el campo?
PurkkaKoodari

3
Entonces, algo que golpea 4 inicia un incendio en casillas adyacentes, pero ¿algo que comienza en 4 o más alto no? Eso no es muy realista.
laszlok

14
"Descargo de responsabilidad: La historia contada en esta pregunta es completamente ficticia e inventada únicamente con el propósito de proporcionar una introducción". -> Comienza con "Soy un granjero malvado [que quiere hacer cosas malvadas]". Muy inteligente. Nadie le relatará los campos ardientes ahora .
J_F_B_M

3
¿Es posible que la ceniza inicial separe el campo en dos, para que esa parte nunca se queme?
aschepler

99
Si el fuego que no se extiende por encima de 4 es demasiado perturbador, imagine que 1-4 es la intensidad que gana el fuego y 5-A representa que se está apagando.
Jeremy Weirich

Respuestas:


1

APL (Dyalog) , 52 bytes *

Asume ⎕IO←0cuál es el valor predeterminado en muchos sistemas. Toma el campo usando 0 para espacios vacíos, 1 para campo que no se quema, 2 para fuego nuevo, 5 para propagación de fuego y 10 para cenizas. La entrada debe ser al menos 3 × 3, lo cual no es un problema ya que las filas y columnas adicionales pueden rellenarse con ceros (espacios en formato OP).

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

Pruébalo en línea!

Mi formato hace que sea difícil verificar la corrección, por lo que aquí hay una versión con procesamiento previo y posterior agregado para traducir desde y hacia el formato de OP.

⍣{... } repite hasta:

 la próxima generación

 es idéntico a

⎕←⍵ la generación actual, producida

{... }⌺3 3 reemplace cada celda con el resultado de esta función aplicada a su vecindario Moore:

 ,⍵ descifrar (aplanar) el argumento; da una lista de nueve elementos

r← asignar a r

4⊃ escoge el cuarto elemento; el centro, es decir, el valor de celda original

c← asignar a c

1= es uno igual a eso?

: si es así, entonces:

  ⍳2 primero en encontrar dedos; 0 1

  9⍴r forma de longitud nueve; 0 1 0 1 0 1 0 1 0

  r/⍨ use eso para filtrar r (esto solo obtiene los vecinos ortogonales)

  4∊ es cuatro un miembro de eso? (es decir, ¿habrá cinco en la próxima generación?)

  1+ Agrega uno; 1 si no se incendió o 2 si se incendió

 más (es decir, el valor actual es 0 o ≥ 2)

  ×c el signo de c

  c+c más eso (es decir, aumentar en uno si está en llamas)

  10⌊ mínimo de diez y eso (ya que la ceniza no se quema)


* En Dyalog Classic, usando en ⎕U233A lugar de .


Pequeño, pero no se ocupa de los cambios en el tablero. Pegado a un 3x3.
Suamere

@Suamere ¿Qué? El tablero no cambia de tamaño, ¿verdad?
Adám

Lo siento, no estaba claro. Su respuesta es asombrosa, pero entiendo que la solución debería permitir una placa de tamaño variable que puede tener o no huecos "a la derecha". No es necesario manejar las brechas en el medio. "A la derecha" parece significar que una tabla de tamaño 15 se construiría como un 4x4, excepto que falta la pieza inferior derecha. Y una placa de tamaño 8 se construiría como un 3x3, excepto que falta la pieza inferior derecha, etc. Así es como leo los requisitos de desafío. Su respuesta es actualmente la más corta, pero solo funciona con un 3x3.
Suamere

@Suamere OP establece claramente que la entrada es 2D. Tomo la entrada como una matriz numérica y permito las ranuras "vacías" en cualquier lugar, en forma de ceros. Si bien requiero que la entrada sea mínima 3 × 3 ( OP lo permitió ) acepto entradas de cualquier tamaño mayor. De hecho, si hace clic en el enlace aquí , verá que mi segundo caso de ejemplo es 2 × 3 con la celda inferior derecha vacía.
Adám

Gotcha No estoy seguro de por qué, pero el enlace Pruébelo aquí tiene problemas (probablemente es mi culpa), aunque su nuevo enlace formateado funciona bien. EG: fire '0A000\n0A0A0\n0A0A0\n000A1'funciona perfectamente en el formateado, pero no puedo obtener un equivalente para trabajar con el primer enlace. Probablemente estoy haciendo algo mal. Esto no funciona para mí: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)

Pruébalo en línea!

-3 bytes gracias a officialaimm al fusionar el otro lambda en f(parece desordenado pero guarda bytes y eso es todo lo que nos importa)
-8 bytes gracias al Sr. Xoder
-26 bytes gracias a ovs
-6 bytes gracias a ppperry


¿Cómo agrego un espacio en blanco, como ese en el ejemplo?
tuskiomi

10

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

Ahorró 2 bytes gracias a la sugerencia 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>

Usos en 9lugar de A. Ingrese como una matriz 2D de enteros. Salida como una matriz de tales matrices.


¿Podría guardar algo usando en 9lugar de A?
Shaggy

7

Simulando el mundo (en Emoji) , 1407 bytes?

¿No te encanta usar una explicación explorable como lenguaje de programación? La desventaja de esto es que generalmente no hay un programa muy bien definido, por lo que en este caso, estoy usando el JSON que exporta. (si tienes alguna idea mejor, házmelo saber)

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

Pruébalo aquí o aquí:

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


6

Retina , 103 96 88 bytes

^
¶
;{:`

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

Pruébalo en línea! Usos 9para cenizas; esto se puede cambiar a un costo de 4 bytes usando T`1-8`2-8A. Editar: Guardado 6 bytes gracias a @MartinEnder. Explicación:

^
¶

Agregue un separador para que las salidas no se encuentren entre sí. (También ayuda cuando coincide a continuación).

;{:`

No imprima el estado final (que es el mismo que el estado anterior que ya se ha impreso). Repita hasta que el pase no cambie el estado. Imprima el estado actual antes de cada pase.

T`0d`d

Avanza la intensidad de todo el fuego.

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

Encienda los campos apagados según corresponda. Subexplicación:

(?<=¶(.)*)

Mida el número de columna de este campo apagado.

0

Empareja el campo apagado.

(?=4

Busque un campo adecuado a la derecha.

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

Busque un campo adecuado en la misma columna (usando un grupo de equilibrio) en la línea a continuación. Tenga en cuenta que si la entrada pudiera garantizarse rectangular entonces esto podría simplificarse |.*¶(?>(?<-1>.)*)4para un ahorro de 3 bytes.

  |(?<=40

Busque un campo adecuado a la izquierda. (Dado que estamos mirando desde el lado derecho del campo, también vemos el campo apagado).

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

Busque un campo adecuado en la misma columna en la línea de arriba. Como se trata de una observación retrospectiva y, por lo tanto, de una coincidencia de derecha a izquierda, la condición del grupo de equilibrio debe aparecer antes de las columnas que el grupo de equilibrio ha hecho coincidir.


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

Pruébalo en línea!

Utiliza '9' en lugar de 'A' para indicar una ubicación quemada.

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

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]

Pruébalo en línea! Uso: htoma un campo como una lista de líneas y devuelve una lista de campos. Un campo sin quemar se indica mediante @y cenizas por 9, los diferentes incendios son los dígitos 1a 8.

  • fgestiona la propagación del fuego de izquierda a derecha mediante la sustitución de todos los @campos no quemados que están justo en un 3campo en llamas con0 .
  • iincrementa cada dígito siempre que sea menor que 9.
  • gaplica fa cada línea, luego invierte la línea, aplica fnuevamente y revierte. Luego se transpone la lista de líneas y nuevamente en cada línea y fse aplica su reverso .
  • hse aplica ga la entrada hasta que ya no cambie y recopile los resultados.

Falla en la entrada "" @ 3 @ 1 \ n @@@ 9 \ n555 @@@@@@@@@@@@@@@@@@@ ", ya que por alguna razón la larga línea de @s cambia a la línea superior después de la primera iteración de fijación que sería grande, gracias.!
Gryphon - Restablecer Mónica

@Gryphon El desplazamiento es causado por la transposición de la matriz de caracteres. Funciona si las otras líneas tienen la misma longitud con algún carácter que no representa un campo, fuego o ceniza, por ejemplo _. Si esto no es aceptable, me temo que tendría que eliminar la respuesta, ya que se centra en el uso de transposey no veo una manera de solucionarlo fácilmente sin introducir 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 una función que toma dos entradas, un puntero a una matriz de cadenas precedidas por su longitud, según lo permitido por este valor predeterminado de E / S. Salidas a STDOUT con una nueva línea final.

Pruébalo en línea!


Se ejecuta para siempre en la entrada 80.
aschepler

@aschepler ¡Lo siento! Asumí que todos los personajes deben convertirse en As, pero aparentemente asumí mal. De todos modos, gracias por la información. Ya está arreglado.
R. Kap


@GiacomoGarabello No puedo creer que me haya olvidado de esa táctica. ¡Gracias por recordarme! :)
R. Kap

4

Octava, 72 69 bytes

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

La entrada se toma como una matriz 2D de números y puntos vacíos marcados con Inf. 'A'ha sido reemplazado por9 . Resultados intermedios (como conjunto de números) impresos implícitamente.

Pruébalo en línea!

Explicación:

En un bucle, la función imdilate(dilatación de la imagen morfológica) del paquete de imágenes se utiliza para simular la propagación del fuego.


1
Esto funciona con tablas de todos los tamaños, e incluso con un montón de agujeros. EG: [0 Inf 0 0 0;0 Inf 0 Inf 0;0 Inf 0 Inf 0;0 0 0 Inf 1]- Muy agradable
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

ftoma la entrada como una matriz 2D de enteros y espacios vacíos marcados con ''. 'A'ha sido reemplazado por9 . La función genera un generador de todos los campos a lo largo del tiempo en el mismo formato.

Pruébalo en línea!


1

Octava , 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 ejecutar, especifique una matriz de caracteres como:

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

... entonces hazlo:

r(f)

Explicación del código a seguir ...

Pruébalo en línea!

Nota: Traté de ejecutar este código con tio.run , pero no obtuve ningún resultado. Tuve que usar otro servicio.


Realmente justo en el momento en que quiero publicar una respuesta de octava, tú respondes antes que yo ..
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;

toma entrada con una nueva línea final de un archivo llamado m; 9para las cenizas

Ejecutar -nro probarlo en línea .


primer enfoque: 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;

toma entrada con una nueva línea final de un archivo llamado m.

Ejecutar -nro probarlo en línea .

Notas de la versión de PHP (para un enfoque antiguo)

  • para PHP anterior a 7.0, reemplace todo después $c-4|con$g[$y+$p=[1,0,-1][$a]][$q+=$x]!="0"||$g[$y+$p][$q]=1;
  • para PHP anterior a 5.5, reemplace [1,0,-1][$a]con$a%2*~-($a&2)
  • para PHP más reciente que 7.0, reemplace a&$ccon ""<$c, +$ccon 0<$cy $c-4con$c!=4

no funciona para otros casos de prueba ... sandbox.onlinephpfunctions.com/code/…
g19fanatic

@ g19fanatic fijo y golf. Gracias por notarlo.
Titus

0

Octava, 419 312 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

Pruébalo en línea!

Esta es mi versión que funciona, así que ahora todavía necesito jugar golf. Creo que puede ser mucho más corto si encuentro una manera de encontrar los índices de los 4 en una matriz, pero no sé cómo.
PD: A es un 9 en mi código.


2
En lugar de endif endfory endwhilepuedes escribirend
rahnema1

0

Plantilla ( modo) , 22 bytes

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

Pruébalo en línea!

Al igual que en la entrada de prueba, use números enteros separados por espacios para 0- 8, ' 'para espacios en blanco y 'A'para A. Recuerde agregar espacios en blanco finales también.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.