Игра Жизни


26

Задний план

Это задание в честь апсиллеров , которые выиграли в номинации « Не все так просто, как кажется » в номинации «Лучшее из PPCG 2016», может ли моя музыкальная шкатулка с 4 нотами сыграть эту песню? Поздравляем!

На своей странице «Обо мне» у этого пользователя есть действительно изящный симулятор для клеточного автомата Game of Life . (Серьезно, иди проверь это.) С другой стороны, слово aspillera в переводе с испанского означает «стрелки». В свете этих фактов, этот вызов о стрелках в игре жизни.

Игра Жизни

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

вход

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

Входные данные гарантированно имеют несколько свойств. Во-первых, его высота равна 2N для некоторого N ≥ 6 , а ширина - не менее 2N + 2 . На входе будут все .s, за исключением того, что где-то в верхних трех рядах находится планер, а в двух средних рядах есть стена блоков. Планер будет лететь на юго-запад или юго-восток, и его положение таково, что если стены будут удалены, он не пройдет через боковой край до достижения нижнего края (но может достигнуть угла сетки). Планер изначально отделен от левого и правого краев хотя бы одним шагом .s. Это может быть на любом этапе.

Стена состоит из блоков, которые разделены одним столбцом .s, за исключением одного места, где они будут разделены как минимум двумя столбцами .s. Как и планер, левый и правый блоки также отделены от краев одним шагом .s. Всегда будет по крайней мере один блок на левом краю и один блок на правом краю.

Вот пример правильной входной сетки:

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

Выход

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

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

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

Если планер пролетает сквозь стену, вы должны вывести истинное значение, а в противном случае - ложное значение. Для приведенного выше примера правильный вывод неверен, так как планер врезается в левую часть стены.

Для целей этой задачи вы можете предположить, что если вы смоделируете GoL на входе для шагов 2 * (высота - 3) , планер находится в нижнем ряду в ожидаемом положении, а стена не повреждена, то вывод верен ,

Правила и оценки

Вы можете написать полную программу или функцию. Побеждает самое низкое число байтов.

Контрольные примеры

Я собрал тестовые случаи в репозиторий GitHub , так как они довольно большие. Вот ссылки на отдельные файлы:


Есть ли причина для включения пустых строк под стеной во вход?
Мартин Эндер

@MartinEnder Они делают решения, в которых вы на самом деле имитируете GoL на входе, более выполнимыми (по крайней мере, я на это надеюсь).
Згарб

Планер всегда будет стартовать в верхнем ряду?
Род

@Rod Да, это будет в верхнем ряду на юго-западе или юго-востоке.
Згарб

Еще одна игра из жизни: P
Кристофер

Ответы:


15

Python 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 Мин

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 Спасибо, сохранил byted
rahnema1

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.