アスキーアートゾンビの侵入シミュレーション


13

ゾンビの侵入をシミュレートするには、マップのグリッドから始めて、マップ#表します。

##   ##
###   #
## ##  
  # ###
#  ####
  • # 土地を表します。
  • 水を表します。

ゾンビは地図上のある地点から始まります...

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

...そして広がります。%ゾンビに感染した土地を示します。

ただし、ゾンビは泳げません。彼らは王がチェスで移動するのと同じ方法で土地を横切ることができます-任意の斜めまたは直交方向に1つの正方形:

!!!
!%!
!!!

シミュレーションの終了時に、一部の土地がゾンビに感染します。

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

あなたの仕事は、ゾンビの侵入をシミュレートすることです。グリッドの初期状態を表す文字列と、初期ゾンビの座標を表す2つの数値を入力として受け取るプログラム(または関数)を記述します。プログラムは、侵略の最終状態を出力(または返す)する必要があります。

仕様書

  • プログラムは、オプションの末尾の改行を出力する場合があります。
  • 入力は正しい形式(スペースが埋め込まれた形式)であり、オプションで末尾の改行があると想定できます。
  • 最初のゾンビは陸上で始まり、すぐには死なないと思います。
  • これはであるため、最短回答(バイト単位)が優先されます。
  • コードが任意のチューリングマシンの停止問題も解決できる場合は、-100%のボーナス。
  • プログラムは、最大50文字のボード幅を処理する必要があります。

停止する問題は何ですか?
ムクルクマール

3
@MukulKumar en.wikipedia.org/wiki/Halting_problem。それは冗談だ。停止問題を解決することは不可能です。
エソランジングフルーツ

1
あなたは決して知らない:P
ムクルクマール


1
いいえ、真剣に、私は停止問題解決のボーナスを-200%に引き上げます。答えはそれに値するでしょう。:)
ルドルフジェリン16

回答:



5

Kotlin、283 218バイト

名前のないラムダ(ネストされた関数を使用)。

ゴルフ

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

非ゴルフ

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
}

再帰的なソリューションに切り替えることで、かなりのバイトを節約しました。


3
「楽しいゾンビ」:P
エソランジングフルーツ

4

JavaScript(ES6)、144バイト

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

where \nは、リテラルの改行文字を表します。0インデックスの座標を取ります。


2

Befunge、324 323バイト

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

オンラインでお試しください!

説明

Befungeでこれを実装することは、ソースコード自体と共有する必要がある80x25文字の「メモリ」に制限されているため、少し複雑でした。50x50マップをその領域に収める秘trickは、2Dマップを1バイトあたり2つのマップ位置を持つ1D配列にフラット化することでした。この1D配列は、Befungeプレイフィールドの80文字幅に収まるように、再び2D配列にラップされます。

感染アルゴリズムは、初期座標をスタックにプッシュする1D配列のオフセットに変換することから始まります。メインループはスタックから値を取得し、そのオフセットのマップ状態を検索します。感染していない土地の場合、感染しているとマークされ、8つの新しいオフセットがスタックにプッシュされます(現在の位置全体の土地を表します)。このプロセスは、スタックが空になるまで続きます。

範囲外の値をチェックする必要を回避するために、マップはすべてのエッジの周りに1文字の水辺で保存されます。


1

ピップ、59バイト

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

複数行の文字列、最初のゾンビの行(インデックスが0)、および最初のゾンビの列(インデックスが0)を受け取る関数。オンラインでお試しください!

どうやって?

Pipには周期的なインデックスが付いているため(通常は良いことですが、マップのエッジをラップさせたくないため、この問題には良くありません)、正規表現の置換ソリューションを探しました。

Ya@?n最初の改行のインデックス(つまり、グリッドの幅)を見つけ、それをにヤンクしyます。

(ac+b+b*Ya@?n):'%上記を実行した後、を計算します(width + 1) * row + col。つまりc+b+b*y、そのインデックスの文字をに設定し%ます。

L2*#aループ2*len(a)時間。これにより、フラッドフィルが完全に伝播するのに十分な反復が得られ、反復カウントが偶数になります(これは重要です)。

.`#(.?.?.{`.y-1.`})?%`0、width-1、width、またはwidth + 1文字の間にが#続くaに一致する正規表現を構築%します。(.最初.の正規表現は改行に一致します。)この正規表現は、次の構成のいずれかに一致します。

#  
 % 

 # 
 % 

  #
 % 

#% 

aR ... '%.@>_この正規表現の一致を、一致の最初の文字%.除くすべての文字の先頭に追加された文字で置き換えます。要するに、交換すると。@>_#%

a:RV ...それを逆にして、に割り当てaます。正規表現は文字列の# %ではなく後だけに一致するため、逆になります。しかし、文字列が逆になった場合、afterはbeforeになり、次の反復で照合できます。これは、反復回数が偶数でなければならない理由でもあります。

ループが完了した後、単に変更された値を返しますa


0

TSQL、267バイト

ゴルフ済み:

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 @

ゴルフをしていない:

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 @

やってみよう


0

PHP、209 189 188 183バイト

ゴルフ可能かもしれない

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;

で実行 php -r '<code>' '<grid>' <y> <x>


0

J、152バイト

あまりよくゴルフされていないので、最後のいくつかのコントロール構造を削除する方法があると確信しています。

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]

フラッドフィルアルゴリズムを実装します。関数gは、fを適用する前に入力を文字配列にフォーマットします。

座標が少し変わっていることに注意してください:

0, 0

左上隅です。最初の座標を増やす:

1, 0

位置をy方向に下に移動します。

それ以外の座標は正常です。

例:

    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.
%%   ##
%%%   #
%% %%  
  % %%%
#  %%%%
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.