Моделювання вторгнення зомбі ASCII-Art


13

Щоб імітувати зомбі-вторгнення, почніть з сітки #та представлення карти:

##   ##
###   #
## ##  
  # ###
#  ####
  • # представляє землю.
  • являє собою воду.

Зомбі починаються в точці на карті ...

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

... і поширити. %позначає землю, заражену зомбі.

Однак зомбі не вміє плавати . Вони можуть переміщатися по землі так само, як король рухається в шахах - один квадрат у будь-якому діагональному чи ортогональному напрямку:

!!!
!%!
!!!

Після закінчення моделювання частина землі буде заражена зомбі:

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

Ваше завдання - імітувати вторгнення зомбі. Напишіть програму (або функцію), яка приймає за введення рядок, що представляє початковий стан сітки, і два числа, що представляють координати початкового зомбі. Програма повинна вивести (або повернути) остаточний стан вторгнення.

Технічні умови

  • Ваша програма може надрукувати необов’язковий прострочений новий рядок.
  • Ви можете припустити, що введення буде у правильному форматі (укладене пробілами) з необов'язковим зворотним рядком.
  • Можна припустити, що початкове зомбі почнеться на суші і не помре одразу.
  • Це , тому найкоротша відповідь (у байтах) виграє.
  • -100% бонус, якщо ваш код також може вирішити проблему зупинки для довільних машин Тьюрінга.
  • Ваша програма повинна обробляти дошки шириною до 50 символів.

що таке проблема зупинки ?
Мукул Кумар

3
@MukulKumar en.wikipedia.org/wiki/Halting_problem . Це жарт. Проблему зупинки вирішити неможливо.
Esolanging Fruit

1
ніколи не знаєш: П
Мукул Кумар


1
Ні, серйозно, я б підняв бонус за вирішення проблеми, що зупиняється, до -200%. Відповідь заслужила б цього. :)
RudolfJelin

Відповіді:



5

Котлін, 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
Esolanging Fruit

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

Де \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 символами "пам'яті", якими потрібно ділитися із самим вихідним кодом. Трюк у встановленні карти 50х50 у цю область полягав у згладженні 2D-карти в 1D-масив із двома місцями розташування на байті. Потім цей 1D масив знову загортається в 2D масив, щоб він міг поміститися в ширину 80 символів ігрового поля Befunge.

Алгоритм зараження починається з перетворення початкових координат у зміщення в 1D-масиві, який він натискає на стек. Основний цикл приймає значення зі стека і шукає стан карти для цього зміщення. Якщо це незаражена земля, вона позначається як заражена, і вісім нових компенсацій висуваються на стек (представляючи землю навколо поточного положення). Цей процес триває, поки стек не порожній.

Щоб уникнути необхідності перевірки значень діапазону, карта зберігається з водною межею з одним символом по всіх краях.


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.`})?%`будує регулярний вираз, який відповідає #послідовності a %, або 0, ширина-1, ширина або ширина + 1 символ між ними. (На .початку введено .в регулярне вираження збігається з новими рядками.) Цей регекс відповідає будь-якій з наступних конфігурацій:

#  
 % 

 # 
 % 

  #
 % 

#% 

aR ... '%.@>_замінює відповідність цього регулярного виразу символом, попередньо призначеним %для .всіх, крім першого символу @>збігу _; Коротше кажучи, замінюючи #з %.

a:RV ...повертає це і присвоює його назад a. Ми реверс , оскільки регулярний вираз відповідає тільки # перед % тим в рядку, а НЕ після; але коли рядок перетворено, після стає раніше, і ми можемо узгодити його на наступній ітерації. Тому також кількість повторень має бути парною.

Після завершення циклу ми просто повертаємо змінене значення 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.
%%   ##
%%%   #
%% %%  
  % %%%
#  %%%%
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.