Gra w strzały

26

tło

To wyzwanie jest na cześć apsillerów , którzy wygrali kategorię Nie tak proste, jak to wygląda w Best of PPCG 2016 z ich wyzwaniem Czy moja 4-nutowa pozytywka może odtworzyć tę piosenkę? Gratulacje!

Na stronie „About Me” ten użytkownik ma naprawdę fajny symulator automatu komórkowego Game of Life . (Poważnie, sprawdź to.) Z drugiej strony słowo aspillera jest po hiszpańsku „podświetlany strzałkami”. W świetle tych faktów to wyzwanie dotyczy strzelnic w Game of Life.

Gra w strzały

W GoL będziemy reprezentować strzałę szybowcem , a ścianę sekwencją bloków . Pojedynczy szybowiec zbliża się do ściany z góry i próbuje przelecieć przez szczelinę w ścianie (podświetloną strzałką). Twoim zadaniem jest sprawdzenie, czy szybowiec przechodzi przez podświetlony strzałkę lub uderza w ścianę.

Wkład

Twój wkład to siatka bitów, która reprezentuje konfigurację GoL. Możesz wziąć go w dowolnym rozsądnym formacie (wieloliniowy ciąg dowolnych dwóch odrębnych drukowalnych znaków ASCII, lista ciągów, tablica liczb całkowitych 2D, tablica boolanów 2D itp.). Dla jasności użyję wieloliniowych ciągów znaków .#poniżej.

Wejście ma zagwarantowane kilka właściwości. Po pierwsze, jego wysokość wynosi 2N dla niektórych N ≥ 6 , a szerokość wynosi co najmniej 2N + 2 . Dane wejściowe będą .s, z wyjątkiem tego, że gdzieś w trzech górnych rzędach znajduje się szybowiec, a w dwóch środkowych rzędach jest ściana bloków. Szybowiec będzie kierował się na południowy zachód lub południowy wschód, a jego położenie będzie takie, że jeśli ściany zostaną usunięte, nie przejdzie on bocznej krawędzi przed osiągnięciem dolnej krawędzi (ale może dotrzeć do rogu siatki). Szybowiec jest początkowo oddzielony od lewej i prawej krawędzi co najmniej jednym krokiem .s. Może być w dowolnej fazie.

Ściana składa się z bloków, które są oddzielone jedną kolumną .s, z wyjątkiem jednego miejsca, w którym będą oddzielone co najmniej dwiema kolumnami .s. Podobnie jak szybowiec, skrajne lewe i prawe bloki są również oddzielone od krawędzi o jeden stopień .s. Zawsze będzie przynajmniej jeden blok na lewej krawędzi i jeden blok na prawej krawędzi.

Oto przykład prawidłowej siatki wejściowej:

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

Wydajność

Jak powiedziano, Twoim zadaniem jest ustalenie, czy szybowiec uderzy w ścianę, czy przebije do południowej krawędzi. Na potrzeby tego wyzwania następuje awaria, jeśli konfiguracja nie składa się już z jednego szybowca i ściany bloków, niezależnie od tego, co stanie się później w symulacji. Poniższe diagramy pokazują najmniejsze szczeliny, przez które szybowiec południowo-wschodni może przejść bez zderzenia w dwóch różnych fazach (warunek dla szybowców południowo-zachodnich jest symetryczny).

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

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

Jeśli szybowiec przeleci przez ścianę, wypiszesz prawdziwą wartość, a w przeciwnym razie wartość fałszu. W powyższym przykładzie prawidłowym wyjściem jest fałsz, ponieważ szybowiec uderzy w lewą część ściany.

Na potrzeby tego wyzwania możesz założyć, że jeśli symulujesz GoL na wejściu dla 2 * (wysokość - 3) kroków, szybowiec znajduje się w dolnym rzędzie w oczekiwanej pozycji, a ściana jest nienaruszona, to wynik jest prawdziwy .

Zasady i punktacja

Możesz napisać pełny program lub funkcję. Wygrywa najniższa liczba bajtów.

Przypadki testowe

Zebrałem przypadki testowe do repozytorium GitHub , ponieważ są one dość duże. Oto linki do poszczególnych plików:

Zgarb
źródło
Czy jest jakiś powód, aby umieszczać puste wiersze pod ścianą na wejściu?
Martin Ender,
@MartinEnder Sprawiają, że rozwiązania, w których faktycznie symulujesz GoL na wejściu, są bardziej wykonalne (przynajmniej mam taką nadzieję).
Zgarb,
Szybowiec zawsze zaczyna się w górnym rzędzie?
Rod
@Rod Tak, będzie w górnym rzędzie, kierując się na południowy zachód lub południowy wschód.
Zgarb,
Kolejna gra życia: P
Christopher

Odpowiedzi:

15

Python 2 , 142 136 135 bajtów

-6 bajtów dzięki ElPedro
-1 bajt dzięki 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

Wypróbuj online! lub Zweryfikuj wszystkie przypadki testowe

Sprawdzanie orientacji (wschód / zachód):

zachód Wschód
Używając, z=p[2].index(1)aby uzyskać pierwszy kwadrat w trzecim rzędzie (reprezentowanym przez czerwony kwadrat), a następnie m=(p[1][z]-p[1][z+1]<1)*2-1odjąć wartość po prawej (zielony) od tego po lewej (niebieski), w ten sposób wszystkie 4 stany szybowców, które zamierzają południowy zachód powoduje 1(górny rząd na obrazie), podczas gdy te idące na południowy wschód powodują 0lub -1.
Następnie przekonwertuj: 1 -> -1i 0,-1 -> 1do użycia w parametrze do odwrócenia list w przypadku list zachodnich. W ten sposób szybowce lecące na południowy zachód są traktowane tak samo jak te lecące na południowy wschód.

Ruch szybowca

szybownictwo
Jest to ruch, który wykonuje szybowiec jadący na południowy wschód, ma wzór „drabiny”, a skrajnie lewy blok w trzeciej linii jest stały dla każdego wzoru. Używając go jako punktu wyjścia, otaczające 3 bloki po lewej i prawej stronie, a środkowe 4 bloki są sprawdzane pod kątem obecności 1s (to byłaby ściana).
strzały
arrowslits_path

Pręt
źródło
Myślę, że możesz stracić 4 bajty, ustawiając zmienną ina 0zewnątrz forpętli, a następnie dodając do niej 1 za każdym razem, a więc pozbądź się enumerate. Wygląda na to, że zadziałało, kiedy wypróbowałem to z TIO. +1 za fajną odpowiedź, czy mam rację, czy nie.
ElPedro,
Miły! Możesz zapisać bajt, usuwając biały znak z 1 in. +1.
Yytsi
2
+1 za „Weast”
JungHwan Min
4

Oktawa, 123 122 108 bajtów

Dzięki @LuisMendo zapisano 2 bajty

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

Wypróbuj online!

Lub

Sprawdź wszystkie przypadki testowe

Dzięki Rod przygotowuje skrzynki testowe.

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

Poprzednia odpowiedź:

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

Najpierw wyodrębnij wzór ściany jako zmienny B.
Wykonuj symulację GoL, aż wzór ściany i symulowany wzór będą miały więcej / mniej niż 5 różnych komórek.
Jeśli szybowiec otrzymał ostatni wiersz, funkcja zwraca true.

rahnema1
źródło
1
aż wzór ściany i wzór symulowany będą miały więcej / mniej niż 5 różnych komórek. To sprytne!
Luis Mendo,
@LuisMendo Dzięki, zapisałem byted
rahnema1
3

Retina , 101 93 91 bajtów

Liczba bajtów zakłada kodowanie ISO 8859-1.

O$#^`.(?=(.*¶)*(?<=#_.\2.+##.(.*¶)\D+))
$#1
¶(?>_(_)*#+_+¶_+¶(?<1>_+¶)*)(?>(?<-1>.)+)_{11}

Wypróbuj online!

Na pewno jeszcze nie optymalne.

Martin Ender
źródło