Simulação ASCII-Art Zombie Invasion

13

Para simular uma invasão de zumbis, comece com uma grade #e representando o mapa:

##   ##
###   #
## ##  
  # ###
#  ####
  • # representa terra.
  • representa água.

Os zumbis começam em um ponto no mapa ...

##   ##
###   #
## %#  
  # ###
#  ####

... e espalhar. %denota terra infectada por zumbis.

No entanto, zumbis não sabem nadar . Eles podem se mover pela terra da mesma maneira que um rei se move no xadrez - um quadrado em qualquer direção diagonal ou ortogonal:

!!!
!%!
!!!

No final da simulação, algumas terras serão infectadas com zumbis:

%%   ##
%%%   #
%% %%  
  % %%%
#  %%%%

Sua tarefa é simular a invasão de zumbis. Escreva um programa (ou função) que tenha como entrada uma string representando o estado inicial da grade e dois números representando as coordenadas do zumbi inicial. O programa deve gerar (ou retornar) o estado final da invasão.

Especificações

  • Seu programa pode imprimir uma nova linha opcional à direita.
  • Você pode supor que a entrada esteja no formato correto (preenchido com espaços), com uma nova linha à direita opcional.
  • Você pode assumir que o zumbi inicial começará em terra e não morrerá imediatamente.
  • Isso é , então a resposta mais curta (em bytes) vence.
  • -100% de bônus se o seu código também puder resolver o Problema da Parada para máquinas de Turing arbitrárias.
  • Seu programa deve lidar com larguras de placa de até 50 caracteres.
Esolanging Fruit
fonte
qual é o problema de parada ?
Mukul Kumar
3
@MukulKumar en.wikipedia.org/wiki/Halting_problem . É uma piada. O problema da parada é impossível de resolver.
Esolanging Fruit
1
você nunca sabe: P
Mukul Kumar
1
Não, sério, eu aumentaria o bônus pela solução do problema de parada para -200%. A resposta mereceria. :)
RudolfJelin

Respostas:

1

APL (Dyalog) , 44 bytes

{{c'%'[⌊⌿'%#'∊¨⍵(c4⊃⍵)]}∘,⌺3 3⍣≡'%'@(⊂⍺)⊢⍵}

Experimente online!

Assume ⎕IO←0.

Argumento esquerdo: linha indexada em 0 rde%, coluna indexada em 0 cde%: r c
argumento correto: matriz de caracteres

Erik, o Outgolfer
fonte
5

Kotlin, 283 218 bytes

Lambda sem nome (com uma função aninhada, heh).

Golfe

{i:String,x:Int,y:Int->val m=i.lines().map{it.toCharArray()};fun v(x:Int,y:Int){try{if(m[y][x]=='#'){m[y][x]='%';for(c in-1..1)for(d in-1..1)if(!(c==0&&d==0))v(x+c,y+d)}}catch(e:Exception){}};v(x, y);m.map(::println)}

Ungolfed

fun zombies(input: String, startX: Int, startY: Int) {
    val m = input.lines().map(String::toCharArray)      // build game map
    fun invade(x: Int, y: Int) {                        // nested functions, woo!
        try {
            if (m[y][x] == '#') {                       // if land
                m[y][x] = '%'                           // mark as invaded
                for (dx in -1..1) {                      // generate neighbour tiles
                    for (dy in -1..1) {
                        if (!(dx == 0 && dy == 0)) {
                            invade(x + dx, y + dy)        // attempt to invade neighbours
                        }
                    }
                }
            }
        } catch(e: Exception) {}                        // catches ArrayIndexOutOfBounds
    }

    invade(startX, startY)                              // start the invasion
    m.map(::println)                                    // print final state
}

Economizou alguns bytes alternando para uma solução recursiva.

Tyler MacDonell
fonte
3
"zumbis divertidos": P
Esolanging Fruit 07/12/16
4

JavaScript (ES6), 144 bytes

(s,x,y,l=s.search`\n`,g=s=>s==(s=s.replace(eval(`/(#|%)(.?[^]{${l-1}}.?)?(?!\\1)[#%]/`),`%$2%`))?s:g(s))=>g(s.slice(0,x+=y*l)+`%`+s.slice(x+1))

Onde \nrepresenta o caractere literal de nova linha. Leva coordenadas indexadas em 0.

Neil
fonte
2

Befunge, 324 323 bytes

&00p&10p20p~$v<p02+g02*!g02:+1$$$$<
 #<%>\"P"/8+p>1+:::~:0`!#v_:85+`!#^_2%\2%3*1+*\2/:"P"%\"P"/8+g+\2/:"P"
:+**73"="+g00*g02g010$$$$<v
02:\-<v/"P"\%"P":/2::_|#:$<:+1+g02\+g02:\-1+g02:\+1:\-1:\+1-g
\:20g^>g:30p\2%3*1+/4%1->#^_::2%6*2+30g+\2/:"P"%\"P"/p:20g-1-
0<v2\g+8/"P"\%"P":/2::<\_@#`0:-g
2^>%3*1+/4%1g,1+:20g%#^_1+55+,\

Experimente online!

Explicação

Implementar isso no Befunge foi um pouco complicado, porque estamos limitados a 80x25 caracteres de "memória", que devem ser compartilhados com o próprio código-fonte. O truque para ajustar um mapa de 50x50 nessa área era achatar o mapa 2D em uma matriz 1D com dois locais de mapa por byte. Esse array 1D é então agrupado em um array 2D novamente, para que possa caber na largura de 80 caracteres do campo de jogo Befunge.

O algoritmo de infecção começa convertendo as coordenadas iniciais em um deslocamento na matriz 1D que ele pressiona na pilha. O loop principal pega um valor da pilha e procura o estado do mapa para esse deslocamento. Se for terreno não infectado, será marcado como infectado e oito novas compensações serão colocadas na pilha (representando o terreno em toda a posição atual). Esse processo continua até que a pilha esteja vazia.

Para evitar ter que verificar valores fora do intervalo, o mapa é armazenado com uma borda de água de um caractere em torno de todas as bordas.

James Holderness
fonte
1

Pip , 59 bytes

{(ac+b+b*Ya@?n):'%L2*#aa:RVaR.`#(.?.?.{`.y-1.`})?%`'%.@>_a}

Uma função que utiliza uma cadeia de linhas múltiplas, a linha do zumbi inicial (indexado 0) e a coluna do zumbi inicial (indexado 0). Experimente online!

Quão?

Como o Pip possui indexação cíclica (geralmente uma coisa boa, mas ruim para esse problema porque não queremos que as bordas do mapa sejam agrupadas), optei por uma solução de substituição de regex.

Ya@?nlocaliza o índice da primeira nova linha (ou seja, a largura da grade) e o puxa y.

(ac+b+b*Ya@?n):'%depois de fazer o acima, calcula (width + 1) * row + col, ou seja c+b+b*y, e define o caractere nesse índice como %.

L2*#aloops 2*len(a)vezes, o que nos fornece iterações suficientes para que o flood flood se propague completamente e garante que a contagem de iterações seja uniforme (isso é importante).

.`#(.?.?.{`.y-1.`})?%`constrói uma regex que corresponde a #seguida por a %, com 0, largura-1, largura ou largura + 1 caracteres no meio. (No .início ., o regex corresponde a novas linhas.) Esse regex corresponde a qualquer uma das seguintes configurações:

#  
 % 

 # 
 % 

  #
 % 

#% 

aR ... '%.@>_substitui correspondências dessa regex pelo caractere %anexado a .todos, exceto o primeiro caractere @>da correspondência _; em suma, substituindo o #por %.

a:RV ...reverte isso e o atribui de volta a a. Nós revertemos porque o regex corresponde apenas # antes % na string, não depois; mas quando a string é invertida, after se torna before e podemos combiná-la na próxima iteração. É também por isso que o número de iterações deve ser uniforme.

Após a conclusão do loop, simplesmente retornamos o valor modificado de a.

DLosc
fonte
0

TSQL, 267 bytes

Golfe:

USE master
DECLARE @ varchar(max)=
'##   ##
###   #
## %#  
  # ###
#  ####'

WHILE @@rowcount>0WITH C as(SELECT x+1i,substring(@,x+1,1)v,x/z r,x%z c
FROM spt_values CROSS APPLY(SELECT number x,charindex(char(10),@)z)z
WHERE type='P'and x<len(@))SELECT @=stuff(@,d.i,1,'%')FROM C,C D
WHERE'#%'=d.v+c.v and abs(c.r-d.r)<2and abs(c.c-d.c)<2PRINT @

Ungolfed:

USE master-- the script needs to be executed on the default master database
DECLARE @ varchar(max)=
'##   ##
###   #
## %#  
  # ###
#  ####'

WHILE @@rowcount>0
WITH C as
(
  SELECT x+1i,substring(@,x+1,1)v,x/z r,x%z c
  FROM
    spt_values
  CROSS APPLY(SELECT number x,charindex(char(10),@)z)z
  WHERE type='P'and x<len(@)
)
SELECT @=stuff(@,d.i,1,'%')FROM C,C D
WHERE'#%'=d.v+c.v and abs(c.r-d.r)<2and abs(c.c-d.c)<2

PRINT @

Experimente

t-clausen.dk
fonte
0

PHP, 209 189 188 183 bytes

pode ser jogável

for($w=strpos($s=($a=$argv)[1],10),$s[$a[2]*++$w+$a[3]]="%";$t<$s;)for($t=$s,$i=0;""<$c=$s[$i++];)if($c>"$")for($y=-2;++$y<2;)for($x=3;$x--;)$s[$p=$i+$y*$w-$x]>"!"?$s[$p]="%":0;echo$s;

Correr com php -r '<code>' '<grid>' <y> <x>

Titus
fonte
0

J, 152 bytes

Não muito bem treinada, tenho certeza de que há uma maneira de remover essas últimas estruturas de controle.

f=:4 :0
c=.(' '"_)`({~&<y)@.((*./y<$x)*.*./y>:0 0)x if.c='#' do.x=.'%'(<y)}x[i=.0 while.i<9 do.i=.>:i[x=.x f y+i<:@(|~,<.@%)3 end.end.x
)
g=:>@cutLF@[f]

Implementa um algoritmo de preenchimento de inundação. A função g formata a entrada em uma matriz de caracteres antes de aplicar f.

Observe que as coordenadas são um pouco estranhas:

0, 0

é o canto superior esquerdo. Aumentando a primeira coordenada:

1, 0

Move a posição para baixo na direção y.

Além disso, as coordenadas são normais.

Exemplo:

    land =: 0 : 0    NB. Define a multi-line string
##   ##
###   #
## ##  
  # ###
#  ####
)

    ] l =. >@cutLF land    NB. Cut 'land' on new lines, and form into an array. Assign to 'l'
##   ##
###   #
## ##  
  # ###
#  ####
    NB. Looks the same, but it isn't.

    '%' (<2 3)} l    NB. 'Infect' the land at 2, 3
##   ##
###   #
## %#  
  # ###
#  ####

    l f 2 3    NB. Flood fill on l (already formatted), starting at 2 3
%%   ##
%%%   #
%% %%  
  % %%%
#  %%%%

    land g 2 3    NB. Flood fill on land, formats for us.
%%   ##
%%%   #
%% %%  
  % %%%
#  %%%%
Bolce Bussiere
fonte