Гра в життя стрілець


26

Фон

Це виклик на честь апсилерів , які виграли категорію не так просто, як це виглядає в Best of PPCG 2016 своїм викликом Чи може моя музична скринька із 4 нотами відтворити цю пісню? Вітаємо!

На своїй сторінці "Про мене" цей користувач має дійсно акуратний симулятор для мобільного автоматичного пристрою Game of Life . (Серйозно, іди перевірити це.) З іншого боку, слово aspillera є іспанським для "стрілець". З огляду на ці факти, це завдання стосується стрілок, що знаходяться в грі життя.

Гра в життя стрілець

У GoL ми будемо представляти стрілку планером , а стіну - послідовністю блоків . Одноплановий планер наближається до стіни зверху і намагається пролетіти через проміжок у стіні (стрілка). Ваше завдання - перевірити, чи планер проходить крізь стрілку стрілки або врізається в стіну.

Вхідні дані

Ваш вхід - це сітка бітів, яка представляє конфігурацію GoL. Ви можете взяти його в будь-якому розумному форматі (багаторядковий рядок будь-яких двох роздрукованих символів ASCII, список рядків, 2D масив цілих чисел, 2D масив булевих і т.д.). Для наочності я буду використовувати багаторядкові рядки символів .#у наступному.

Гарантія має кілька властивостей. По-перше, його висота для деяких N ≥ 6 становить 2N , а ширина - щонайменше 2N + 2 . Вхід буде всім s, за винятком того, що десь на верхніх трьох рядах є планер, а на двох середніх рядах - стінка з блоків. Планер буде прямувати на південний захід або південний схід, і його положення таке, що якщо стіни будуть видалені, він не пройде через бічний край, перш ніж досягти нижнього краю (але може досягти кута сітки). Планер спочатку відокремлюється від лівого та правого країв щонайменше на один крок s. Це може бути в будь-якій фазі...

Стіна складається з блоків, які розділені одним стовпцем .s, за винятком одного місця, де вони будуть розділені щонайменше двома колонами .s. Як і планер, крайній лівий і правий блоки також відокремлюються від країв на один крок .s. Завжди буде принаймні один блок з лівого краю та один блок з правого краю.

Ось приклад дійсної вхідної сітки:

....#......................
..#.#......................
...##......................
...........................
...........................
...........................
.##.##............##.##.##.
.##.##............##.##.##.
...........................
...........................
...........................
...........................
...........................
...........................

Вихідні дані

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

...#...........
.#.#...........
..##...........
...............
...............
##...........##
##...........##

...#...........
....#..........
..###..........
...............
...............
##...........##
##...........##

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

Для цілей цього виклику ви можете припустити, що якщо імітувати GoL на вході для 2 * (висота - 3) кроків, планер знаходиться в нижньому ряду в очікуваному положенні, а стінка є цілою, то вихід є трикучим .

Правила та оцінка

Ви можете написати повну програму або функцію. Виграє найменший байт.

Тестові справи

Я зібрав тестові випадки у сховище GitHub , оскільки вони досить великі. Ось посилання на окремі файли:


Чи є якась причина для включення порожніх рядків під стіною у вхід?
Мартін Ендер

@MartinEnder Вони роблять рішення, де ви насправді моделюєте GoL на вході, більш здійсненними (принаймні, я сподіваюся, що так).
Згарб

Планер завжди буде стартувати у верхньому ряду?
Пруд

@Rod Так, це буде в верхньому ряду, що прямує на південний захід або південний схід.
Згарб

Ще одна гра життя: П
Крістофер

Відповіді:


15

Пітон 2 , 142 136 135 байт

-6 байт завдяки ElPedro
-1 байт завдяки TuukkaX

p=input()
z=p[2].index(1)
m=(p[1][z]-p[1][z+1]<1)*2-1
k=i=0
for b in p[3:]:x=p[2][::m].index(1)+i;k|=1in b[::m][x-2:x+8];i+=1
print 1-k

Спробуйте в Інтернеті! або Перевірте всі тестові випадки

Перевірка орієнтації (схід / захід):

захід схід
Використовуючи z=p[2].index(1)для отримання першого квадрата в 3-му ряду (представленого червоним квадратом), а потім m=(p[1][z]-p[1][z+1]<1)*2-1для віднімання значення праворуч (зелений) від лівого зліва (синього), таким чином, усі 4 стану планера, які збираються південно-західний результат у 1(верхній рядок на зображенні), тоді як ті, що йдуть на південний схід, призводять до 0або -1.
Потім конвертуйте: 1 -> -1і 0,-1 -> 1буде використовуватися за параметром для зворотного переліку списків при роботі із західними. Таким чином, планери, що йдуть на південний захід, обробляються так само, як і на південному сході.

Планерний рух

ковзання
Це рух, який здійснює планер, що прямує на південний схід, він має "сходи", і крайній лівий блок на 3-й лінії є постійним для кожного малюнка. Використовуючи його як вихідну точку, навколишні 3 блоки зліва та справа, а середні 4 блоки перевіряють на наявність 1s (це була б стіна).
стрілочки
arrowslits_path


Я думаю, що ви можете втратити 4 байти, встановивши змінну iна 0зовнішнє forцикл, потім додаючи до неї 1 пропуск кожного разу, і так позбудетесь enumerate. Здається, працює, коли я спробував це з вашим TIO. +1 за класну відповідь, я прав чи не прав.
ElPedro

Приємно! Ви можете зберегти байт, видаливши з нього пробіл 1 in. +1.
Yytsi

2
+1 для "weast"
JungHwan Min

4

Октава, 123 122 108 байт

Завдяки @LuisMendo збережено 2 байти

B=A=input("");B(1:3,:)=0;do;until nnz((A=A&(s=conv2(A,(m=-1:1)|m','same'))>1&s<4|~A&s==3)-B)-5;any(A(end,:))

Спробуйте в Інтернеті!

Або

Перевірте всі тестові випадки

Завдяки Роду готують тестові справи.

B=A=input("");
B(1:3,:)=0;
do
until nnz((A=A&(s=conv2(A,(m=-1:1)|m','same'))>1&s<4|~A&s==3)-B)-5
any(A(end,:))

Попередня відповідь:

B=A=input("");
B(1:3,:)=0;
while nnz(A~=B)==5
    s=conv2(A,(m=-1:1)|m','same');
    x=~A;
    A&=~A|~(s<2|s>3);
    A|=x&s==3;
end;
any(A(end,:))

Спочатку витягніть стіновий візерунок як змінний B.
Робіть моделювання GoL до тих пір, поки на стіновому малюнку та на модельованому малюнку не буде більше / менше 5 різних комірок.
Якщо планер отримав останній рядок, функція повертає значення true.


1
до тих пір, поки на стіновому малюнку та імітованому малюнку не буде більше / менше 5 різних комірок. Це розумно!
Луїс Мендо

@LuisMendo Спасибі, врятував байт
rahnema1

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