ASCII-Art Zombie Invasion Simulation


13

Per simulare un'invasione di zombi, inizia con una griglia di #e che rappresenta la mappa:

##   ##
###   #
## ##  
  # ###
#  ####
  • # rappresenta la terra.
  • rappresenta l'acqua.

Gli zombi iniziano in un punto della mappa ...

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

... e diffondere. %indica la terra infettata dagli zombi.

Tuttavia, gli zombi non possono nuotare . Possono muoversi attraverso la terra nello stesso modo in cui un re si muove negli scacchi - un quadrato in qualsiasi direzione diagonale o ortogonale:

!!!
!%!
!!!

Alla fine della simulazione, alcune terre saranno infettate dagli zombi:

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

Il tuo compito è simulare l'invasione di zombi. Scrivi un programma (o una funzione) che accetta come input una stringa che rappresenta lo stato iniziale della griglia e due numeri che rappresentano le coordinate dello zombi iniziale. Il programma dovrebbe generare (o restituire) lo stato finale dell'invasione.

specificazioni

  • Il programma potrebbe stampare una nuova riga finale opzionale.
  • Puoi supporre che l'input sia nel formato corretto (riempito con spazi), con una nuova riga finale opzionale.
  • Puoi presumere che lo zombi iniziale inizi a terra e non morirà immediatamente.
  • Questo è , quindi vince la risposta più breve (in byte).
  • -100% di bonus se il tuo codice può anche risolvere il problema di interruzione per macchine Turing arbitrarie.
  • Il tuo programma dovrebbe gestire larghezze della scheda fino a 50 caratteri.

qual è il problema di arresto ?
Mukul Kumar,

3
@MukulKumar en.wikipedia.org/wiki/Halting_problem . È uno scherzo. Il problema dell'arresto è impossibile da risolvere.
Esolanging Fruit il

1
non si sa mai: P
Mukul Kumar il


1
No, sul serio, aumenterei il bonus per la soluzione del problema di arresto al -200%. La risposta lo meriterebbe. :)
RudolfJelin

Risposte:


1

APL (Dyalog) , 44 byte

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

Provalo online!

Assume ⎕IO←0.

Argomento sinistro: riga 0 indicizzata rdi%, colonna indicizzata 0 cdi%: r c
argomento destro: matrice di caratteri


5

Kotlin, 283 218 byte

Lambda senza nome (con una funzione nidificata, heh).

golfed

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

Risparmiato parecchi byte passando a una soluzione ricorsiva.


3
"zombi divertenti": P
Esolanging Fruit

4

JavaScript (ES6), 144 byte

(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))

Dove \nrappresenta il carattere letterale di newline. Accetta le coordinate indicizzate 0.


2

Befunge, 324 323 byte

&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+,\

Provalo online!

Spiegazione

L'implementazione di questo in Befunge è stata un po 'complicata perché siamo limitati a 80x25 caratteri di "memoria" che devono essere condivisi con il codice sorgente stesso. Il trucco per adattare una mappa 50x50 in quell'area era appiattire la mappa 2D in un array 1D con due posizioni della mappa per byte. Questo array 1D viene quindi nuovamente avvolto in un array 2D in modo da adattarsi alla larghezza di 80 caratteri del campo di gioco di Befunge.

L'algoritmo di infezione inizia convertendo le coordinate iniziali in un offset nell'array 1D che inserisce nello stack. Il ciclo principale prende un valore dallo stack e cerca lo stato della mappa per quell'offset. Se è una terra non infetta, viene contrassegnata come infetta e otto nuovi offset vengono inseriti nella pila (che rappresenta la terra tutt'attorno alla posizione corrente). Questo processo continua fino a quando lo stack è vuoto.

Per evitare di dover cercare valori fuori intervallo, la mappa viene memorizzata con un bordo d'acqua di un carattere attorno a tutti i bordi.


1

Pip , 59 byte

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

Una funzione che accetta una stringa multilinea, la riga dello zombie iniziale (0-indicizzato) e la colonna dello zombie iniziale (0-indicizzato). Provalo online!

Come?

Poiché Pip ha l'indicizzazione ciclica (di solito è una buona cosa, ma non va bene per questo problema perché non vogliamo che i bordi della mappa vengano spostati), ho optato per una soluzione di sostituzione regex.

Ya@?ntrova l'indice della prima newline (ovvero la larghezza della griglia) e lo inserisce y.

(ac+b+b*Ya@?n):'%dopo aver fatto quanto sopra, calcola (width + 1) * row + col, cioè c+b+b*y, e imposta il carattere su quell'indice su %.

L2*#ai 2*len(a)tempi dei cicli , che ci danno abbastanza iterazioni per il riempimento dell'inondazione da propagarsi completamente e assicurano che il conteggio delle iterazioni sia pari (è importante).

.`#(.?.?.{`.y-1.`})?%`costruisce una regex che corrisponde a #seguita da a %, con 0, larghezza-1, larghezza o larghezza + 1 caratteri tra. (L' .inizio fa sì che .regex corrisponda a nuove righe.) Questa regex corrisponde a una delle seguenti configurazioni:

#  
 % 

 # 
 % 

  #
 % 

#% 

aR ... '%.@>_sostituisce le partite di questa regex con il personaggio %anteposto a .tutti tranne il primo personaggio @>della partita _; in breve, sostituendo #con %.

a:RV ...lo inverte e lo riassegna a a. Invertiamo perché il regex corrisponde solo # prima % nella stringa, non dopo; ma quando la stringa viene invertita, dopo diventa prima e possiamo abbinarla alla successiva iterazione. Questo è anche il motivo per cui il numero di iterazioni deve essere pari.

Al termine del ciclo, restituiamo semplicemente il valore modificato di a.


0

TSQL, 267 byte

golfed:

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 @

Provalo


0

PHP, 209 189 188 183 byte

può essere golfabile

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;

Corri con php -r '<code>' '<grid>' <y> <x>


0

J, 152 byte

Non molto bene, sono sicuro che c'è un modo per rimuovere quelle ultime strutture di controllo.

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 un algoritmo di riempimento flood. La funzione g formatta l'input in una matrice di caratteri prima di applicare f.

Nota che le coordinate sono un po 'strane:

0, 0

è l'angolo in alto a sinistra. Aumentare la prima coordinata:

1, 0

Sposta la posizione verso il basso nella direzione y.

Diverso da quello coordinate sono normali.

Esempio:

    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.
%%   ##
%%%   #
%% %%  
  % %%%
#  %%%%
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.