Simulasi Invasi Zombie ASCII-Seni

13

Untuk mensimulasikan invasi zombie, mulailah dengan kisi #dan yang mewakili peta:

##   ##
###   #
## ##  
  # ###
#  ####
  • # mewakili tanah.
  • mewakili air.

Zombi dimulai pada titik di peta ...

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

... dan menyebar. %menunjukkan tanah yang terinfeksi oleh zombie.

Namun, zombie tidak bisa berenang . Mereka dapat bergerak melintasi tanah dengan cara yang sama seperti seorang raja bergerak dalam catur - satu kotak di setiap arah diagonal atau ortogonal:

!!!
!%!
!!!

Di akhir simulasi, beberapa lahan akan terinfeksi zombie:

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

Tugas Anda adalah untuk mensimulasikan invasi zombie. Tulis program (atau fungsi) yang mengambil input string yang mewakili keadaan awal grid, dan dua angka yang mewakili koordinat zombie awal. Program harus menampilkan (atau mengembalikan) keadaan akhir invasi.

Spesifikasi

  • Program Anda dapat mencetak baris tambahan opsional.
  • Anda dapat berasumsi bahwa input akan berada dalam format yang benar (diisi dengan spasi), dengan baris tambahan opsional.
  • Anda dapat mengasumsikan zombie awal akan mulai di darat dan tidak akan langsung mati.
  • Ini adalah , jadi jawaban tersingkat (dalam byte) menang.
  • -100% bonus jika kode Anda juga dapat menyelesaikan Masalah Pemutusan untuk mesin Turing yang berubah-ubah.
  • Program Anda harus menangani lebar papan hingga 50 karakter.
Buah Esolanging
sumber
apa yang menghentikan masalah ?
Mukul Kumar
3
@MukulKumar en.wikipedia.org/wiki/Halting_problem . Itu lelucon. Masalah Henti tidak mungkin diselesaikan.
Buah Esolanging
1
Anda tidak pernah tahu: P
Mukul Kumar
1
Tidak, serius, saya akan mengangkat bonus untuk solusi masalah berhenti menjadi -200%. Jawabannya pantas mendapatkannya. :)
RudolfJelin

Jawaban:

1

APL (Dyalog) , 44 byte

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

Cobalah online!

Diasumsikan ⎕IO←0.

Argumen kiri: 0-indexed row rof%, 0-indexed kolom cof%: r c
Argumen kanan: Character matrix

Erik the Outgolfer
sumber
5

Kotlin, 283 218 byte

Lambda tanpa nama (dengan fungsi bersarang, heh).

Golf

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

Tidak disatukan

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
}

Menyimpan beberapa byte dengan beralih ke solusi rekursif.

Tyler MacDonell
sumber
3
"zombie yang menyenangkan": 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))

Dimana \nmewakili karakter baris baru literal. Membawa koordinat 0-diindeks.

Neil
sumber
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+,\

Cobalah online!

Penjelasan

Menerapkan ini di Befunge sedikit rumit karena kita terbatas pada 80x25 karakter "memori" yang harus dibagikan dengan kode sumber itu sendiri. Trik untuk memasang peta 50x50 ke area itu adalah meratakan peta 2D ke dalam array 1D dengan dua lokasi peta per byte. Array 1D ini kemudian dibungkus menjadi array 2D lagi sehingga bisa masuk dalam lebar 80 karakter dari arena bermain Befunge.

Algoritma infeksi dimulai dengan mengubah koordinat awal menjadi offset di larik 1D yang didorong ke tumpukan. Loop utama mengambil nilai dari stack dan mencari status peta untuk offset itu. Jika itu adalah tanah yang tidak terinfeksi, maka akan ditandai sebagai terinfeksi, dan delapan offset baru didorong ke tumpukan (mewakili tanah di sekitar posisi saat ini). Proses ini berlanjut hingga tumpukan kosong.

Untuk menghindari keharusan memeriksa nilai di luar kisaran, peta disimpan dengan batas air satu karakter di sekitar semua tepi.

James Holderness
sumber
1

Pip , 59 byte

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

Sebuah fungsi yang mengambil string multiline, deretan zombie awal (0-diindeks), dan kolom zombie awal (0-diindeks). Cobalah online!

Bagaimana?

Karena Pip memiliki pengindeksan siklus (biasanya hal yang baik, tetapi buruk untuk masalah ini karena kami tidak ingin tepi peta untuk membungkus), saya pergi untuk solusi penggantian regex.

Ya@?n menemukan indeks baris baru pertama (yaitu lebar kotak) dan menariknya ke dalam y .

(ac+b+b*Ya@?n):'%setelah melakukan hal di atas, hitung (width + 1) * row + col, yaitu c+b+b*y, dan set karakter pada indeks itu menjadi %.

L2*#aloop 2*len(a)kali, yang memberi kita iterasi yang cukup untuk mengisi banjir untuk sepenuhnya menyebar dan memastikan jumlah iterasi genap (itu penting).

.`#(.?.?.{`.y-1.`})?%`membangun regex yang cocok dengan #diikuti oleh %, dengan 0, lebar-1, lebar, atau lebar + 1 karakter di antaranya. (The .di awal membuat .di regex match newlines.) Regex ini cocok dengan salah satu dari konfigurasi berikut:

#  
 % 

 # 
 % 

  #
 % 

#% 

aR ... '%.@>_mengganti korek api regex ini dengan karakter yang %didahulukan untuk .semua kecuali karakter pertama @>dari korek api _; singkatnya, mengganti #dengan% .

a:RV ...membalikkan itu dan mengembalikannya ke a. Kami membalikkan karena regex hanya cocok # sebelum % di string, bukan setelah; tetapi ketika string dibalik, setelah menjadi sebelum dan kita bisa mencocokkannya pada iterasi berikutnya. Ini juga mengapa jumlah iterasi harus genap.

Setelah loop selesai, kami cukup mengembalikan nilai yang dimodifikasi dari a.

DLosc
sumber
0

TSQL, 267 byte

Golf:

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 @

Tidak Disatukan:

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 @

Cobalah

t-clausen.dk
sumber
0

PHP, 209 189 188 183 byte

mungkin golf

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;

Jalankan dengan php -r '<code>' '<grid>' <y> <x>

Titus
sumber
0

J, 152 Bytes

Tidak bermain golf dengan baik, saya yakin ada cara untuk menghapus beberapa struktur kontrol terakhir.

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]

Menerapkan algoritma pengisian banjir. Fungsi g memformat input ke dalam array karakter sebelum menerapkan f.

Perhatikan bahwa koordinat agak aneh:

0, 0

adalah sudut kiri atas. Meningkatkan koordinat pertama:

1, 0

Memindahkan posisi ke bawah ke arah y.

Selain itu koordinatnya normal.

Contoh:

    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
sumber