ASCII-Art Zombi İstilası Simülasyonu


13

Bir zombi istilasını simüle etmek için haritanın bir ızgarasıyla #ve temsiliyle başlayın :

##   ##
###   #
## ##  
  # ###
#  ####
  • # araziyi temsil eder.
  • suyu temsil eder.

Zombiler haritadaki bir noktada başlar ...

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

... ve yayıldı. %"Zombiler", zombiler tarafından enfekte olmuş arazileri belirtir.

Ancak zombiler yüzemez . Bir kralın satrançta hareket ettiği gibi karada da hareket edebilirler - herhangi bir çapraz veya dikey yönde bir kare:

!!!
!%!
!!!

Simülasyonun sonunda, bazı topraklara zombi bulaşacaktır:

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

Göreviniz zombi istilasını simüle etmektir. Gridin başlangıç ​​durumunu temsil eden bir dize ve ilk zombi koordinatlarını temsil eden iki sayı girdi olarak alan bir program (veya işlev) yazın. Program işgalin son halini vermeli (veya geri vermelidir).

Özellikler

  • Programınız isteğe bağlı bir son satır basabilir.
  • Girdinin, isteğe bağlı bir satırsonu çizgisiyle doğru biçimde (boşluklarla doldurulmuş) olacağını varsayabilirsiniz.
  • İlk zombi karada başlayacağını ve hemen ölmeyeceğini varsayabilirsiniz.
  • Bu , bu yüzden en kısa cevap (bayt cinsinden) kazanır.
  • Kodunuz isteğe bağlı Turing makineleri için Durdurma Sorununu da çözebilirse% 100 bonus .
  • Programınız 50 karaktere kadar olan pano genişliklerini işlemelidir.

nedir durdurulması sorun ?
Mukul Kumar

3
@MukulKumar en.wikipedia.org/wiki/Halting_problem . Bu bir şaka. Durdurma Problemini çözmek imkansızdır.
Esolanging Fruit

1
Asla bilemezsiniz: P
Mukul Kumar


1
Hayır, cidden, durma problemi çözümü için bonusu% -200'e yükseltirdim. Cevap bunu hak ederdi. :)
RudolfJelin

Yanıtlar:


1

APL (Dyalog) , 44 bayt

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

Çevrimiçi deneyin!

Varsayım ⎕IO←0.

Sol bağımsız değişken: 0 dizinli r% satırı , 0 dizinli c% sütunu : r c
Sağ bağımsız değişken: Karakter matrisi


5

Kotlin, 283 218 bayt

Adsız lambda (iç içe geçmiş işlevli, 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
}

Özyinelemeli bir çözüme geçerek birkaç bayt tasarruf etti.


3
"eğlenceli zombiler": P
Esolanging Meyve

4

JavaScript (ES6), 144 bayt

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

Burada \ngerçek satırsonu karakterini temsil eder. 0 indeksli koordinatlar alır.


2

Befunge, 324 323 bayt

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

Çevrimiçi deneyin!

açıklama

Bunu Befunge'de uygulamak biraz karmaşıktı çünkü kaynak kodun kendisiyle paylaşılması gereken 80x25 karakter "bellek" ile sınırlıyız. Bu alana 50x50'lik bir harita yerleştirmenin hilesi, 2B haritayı bayt başına iki harita konumuyla 1D dizisine düzleştirmekti. Bu 1D dizisi daha sonra Befunge oyun alanının 80 karakter genişliğine sığabilmesi için tekrar bir 2D diziye sarılır.

Enfeksiyon algoritması, başlangıç ​​koordinatlarını yığına doğru ittiği 1D dizisindeki bir ofsete dönüştürerek başlar. Ana döngü yığından bir değer alır ve bu ofset için harita durumunu arar. Enfekte olmamış arazi ise, virüslü olarak işaretlenir ve yığına sekiz yeni ofset itilir (mevcut konumun çevresindeki araziyi temsil eder). Bu işlem, yığın boşalana kadar devam eder.

Aralık dışı değerleri kontrol etmek zorunda kalmamak için, harita tüm kenarlarda tek karakterli bir su kenarlığı ile saklanır.


1

Pip , 59 bayt

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

Çok satırlı bir dize, ilk zombi satırı (0 dizinli) ve ilk zombi sütunu (0 dizinli) alan bir işlev. Çevrimiçi deneyin!

Nasıl?

Pip'in döngüsel indekslemesi olduğundan (genellikle iyi bir şeydir, ancak harita kenarlarının sarılmasını istemediğimiz için bu sorun için kötüdür), normal ifade değiştirme çözümüne gittim.

Ya@?nilk satırsonunun dizinini (ör. ızgaranın genişliği) bulur ve içine çeker y.

(ac+b+b*Ya@?n):'%Yukarıdakileri yaptıktan sonra , o dizindeki karakteri hesaplar (width + 1) * row + col, yani c+b+b*yayarlar ve ayarlar %.

L2*#aFlood 2*len(a)dolgusunun tam olarak yayılması için yeterli iterasyonlar veren ve yineleme sayısının eşit olduğundan emin olmak için süreleri döngüler (bu önemlidir).

.`#(.?.?.{`.y-1.`})?%`a eşleşen düzenli ifade yapılarının #bir takip %arasında ya 0, genişlik-1, genişlik, ya da genişlik + 1 karakter. ( .Başlangıçta .normal ifade eşleme satırlarını eşleştirir.) Bu normal ifade aşağıdaki yapılandırmalardan herhangi biriyle eşleşir:

#  
 % 

 # 
 % 

  #
 % 

#% 

aR ... '%.@>_bu normal ifadenin eşleşmelerini , eşleşmenin ilk karakteri hariç herkese %eklenmiş .karakterle değiştirir ; Kısacası, değiştirilmesi ile .@>_#%

a:RV ...tersine çevirir ve geri atar a. Biz tersine çünkü regex sadece dizede # önce eşleşir %, sonra değil; ancak dize ters çevrildiğinde, daha önce olur ve bir sonraki yinelemede eşleştirebiliriz. Bu nedenle yineleme sayısının eşit olması gerekir.

Döngü tamamlandıktan sonra, yalnızca değiştirilen değerini döndürürüz a.


0

TSQL, 267 bayt

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 @

Denemek


0

PHP 209 189 188 183 bayt

golf oynayabilir

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;

Şununla koş: php -r '<code>' '<grid>' <y> <x>


0

J, 152 Bayt

Çok iyi golf oynamadı, eminim bu son birkaç kontrol yapısını kaldırmanın bir yolu var.

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]

Bir taşkın dolgu algoritması uygular. G işlevi f'yi uygulamadan önce girişi bir karakter dizisine formatlar.

Koordinatların biraz garip olduğunu unutmayın:

0, 0

sol üst köşedir. İlk koordinatı artırmak:

1, 0

Konumu y yönünde aşağı taşır.

Bunun dışında koordinatlar normaldir.

Misal:

    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.
%%   ##
%%%   #
%% %%  
  % %%%
#  %%%%
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.