tło
W Bejeweled i podobnych grach gracz musi zamienić dowolne dwa sąsiednie klejnoty (bez przekątnych) w siatce klejnotów 8x8, aby dopasować trzy tego samego koloru z rzędu. Klejnoty można dopasowywać poziomo lub pionowo. Rozgrywka trwa, dopóki nie będzie żadnego ruchu, który można wykonać, co spowoduje trzy z rzędu, w którym to momencie gra się kończy.
Zadanie
Celem jest napisanie programu, który określa, czy gra w Bejeweled jeszcze się nie skończyła. Innymi słowy, musi sprawdzić, czy możliwy jest ruch, który daje co najmniej trzy z rzędu. Mogą być więcej niż trzy klejnoty z rzędu i nadal jest to prawidłowy ruch.
Wejście
Twój program musi zaakceptować za pomocą standardowego wejścia reprezentację 8x8 siatki Bejeweled. Każdy z siedmiu kolorów klejnotów będzie reprezentowany przez cyfrę od 1 do 7. Każda linia będzie zawierać jeden wiersz i wprowadzonych zostanie 8 linii, każda składająca się z 8 cyfr. Zobacz przykłady. Możesz założyć, że dane wejściowe będą zawsze zgodne z tym formatem i nigdy nie będą już zawierać trzech z rzędu.
Wynik
Program musi następnie wyprowadzić (na standardowe wyjście) yes
lub w no
zależności od tego, czy istnieje co najmniej jeden prawidłowy ruch, który spowodowałby trzy lub więcej klejnotów z rzędu. Twój program nie może wypisywać niczego poza pojedynczą instancją jednego yes
lub jednego no
.
Zasady
Twój program nie może używać żadnych zewnętrznych plików ani zasobów, argumentów wiersza poleceń ani wymagać określonej nazwy pliku. Program z najmniejszą liczbą bajtów w kodzie źródłowym wygrywa.
Przykłady
Wejście:
12314131
13224145
54762673
61716653
61341144
23453774
27645426
75575656
Wynik: yes
Wejście:
35261546
76421754
15743271
62135642
35617653
64565476
54427254
15635465
Wynik: no
Zobacz odpowiedź MT0 poniżej na dodatkowe przypadki testowe.
Odpowiedzi:
Oryginalne rozwiązanie: JavaScript -
261255228227179153 znakówZakładając, że łańcuch do testu jest w zmiennej
s
(aby to funkcjaf
następnie dodaćf=s=>
do początku kodu lub, inaczej, aby pobierać dane z wiersza następnie zastąpićs
zprompt()
).Dane wyjściowe są przesyłane do konsoli.
3 rd rozwiązanie: JavaScript (ECMAScript 6): - 178 znaków
Wziąłem 2 nd rozwiązanie, poniżej, (który używa wyrażeń regularnych do sprawdzania znaków w niektórych konfiguracjach) i przerobiony go po prostu sprawdzić ciąg dla identycznych znaków w tych samych konfiguracjach bez użycia wyrażeń regularnych.
Ciąg Base-36
"2313ab1b8a2a78188h9haj9j8iaiir9r"
daje par przesunięć, by sprawdzić - czyli pary23
wyników w czeku, jeśli I th znak jest identyczny z (i + 2) th charakteru i (i + 3) th charakteru (odpowiednik wyrażenia regularnego(.).\1\1
- z pewnymi dodatkowymi kontrolami, aby upewnić się, że nieidentyczny znak nie jest znakiem nowej linii).2 II rozwiązanie: JavaScript (ECMAScript 6) - 204 znaków
Buduje wiele wyrażeń regularnych (więcej szczegółów poniżej) przy użyciu par wartości pobranych z ciągu Base-18
10907160789879h8
i wykonujeOR
wszystkie testy. Aby jeszcze bardziej to zmniejszyć, możesz zauważyć, że wyrażenia regularne występują w parach, gdzie jedno jest „odwrotnością” drugiego (ignorując wyrażenia regularne dla 3-z rzędu poziomo i pionowo, ponieważ OP wskazuje, że nigdy nie będą obecne - jeśli chcesz dodać te testy z powrotem w dołączeniu0088
do ciągu Base-18).Wyjaśnienie
Zacznij od 16 wyrażeń regularnych obejmujących wszystkie możliwe konfiguracje prawidłowych ruchów:
( Uwaga: regexs do 3 w jednej linii w poziomie 0 ( TH ) i pionowo (część 9 TH ) mają znaczenia jak wskazuje PO, że środki do dopasowania ich nie będzie obecny. )
Testowanie każdego z tych danych wejściowych określi, czy można znaleźć prawidłowy ruch tej konfiguracji.
Jednak wyrażenia regularne można łączyć, aby uzyskać następujące 6:
Można je następnie połączyć w jedno wyrażenie regularne:
Który po prostu musi zostać przetestowany względem danych wejściowych.
Przypadki testowe
Niektóre przypadki testowe, które inne osoby mogą uznać za przydatne (nie są zgodne z formatem wejściowym polegającym na stosowaniu tylko cyfr 1-7, ale można to łatwo poprawić i jest to tylko siatka 8x4 - ponieważ jest to minimum wymagane do testu wszystkich prawidłowych danych wejściowych ).
W formacie mapy z ciągu wejściowego, do którego pasuje 16 wyrażeń regularnych powyżej.
Edytuj 1
Zamień
\d
s na.
- zapisuje 6 znaków.Edytuj 2
Wymień
(?:.|\n)
się[\s\S]
i usuwane dodatkowych grup spoza przechwytywanie i zaktualizowanych odniesień tyłu (jak sugeruje m-Buettner ) i dodano w tak / nie wyjście.Edytuj 3
Edytuj 4
Dodano kolejne (krótsze) rozwiązanie i dwa kolejne niepasujące przypadki testowe.
Edytuj 5
Edytuj 6
źródło
?'yes':'no'
liczbę swoich znaków dla uczciwości, ponieważ jest to zgodne z wymogami i wszyscy inni go używają..
dopasowania dowolnego znaku, w tym nowego wiersza? W przypadku Perla łączone wyrażenie regularne ma zaledwie 129 bajtów (co jest leniwe, skompilowałem z Regexp :: Assemble ), więc cały program Perla ma około 150 bajtów..{8}|.{9}
z.{8,9}
i.{7}|.{8}
z.{7,8}
Python 383
Tylko jedna * linia Pythona!
* Cóż, z średnikami, ale w pythonie wciąż nie jest to trywialne (jednowierszowe python są fajne! )
źródło
Node.js - Naiwne rozwiązanie - 905 bajtów
Cóż, jeszcze nie ma odpowiedzi, więc opublikuję naprawdę naiwne rozwiązanie w Node.js
Przechodzi przez każdy możliwy ruch, a następnie testuje powstałą planszę, aby sprawdzić, czy są 3 z rzędu.
Gra w golfa (z kompilatorem zamykającym google) (niektóre tam hacky rzeczy, takie jak! 0 i! 1; nawet nie jestem pewien, co zrobił z moją zamianą XOR)
Pamiętaj, że napisałem to wszystko na telefonie komórkowym i nie mam czasu na testowanie ani nic takiego. Skomentuj, jeśli zobaczysz jakieś błędy, sprawdzę to później.
Wersja do gry w golfa dla ludzi
źródło
Perl,
11496959392878685 bajtówObejmuje + dla
-a0p
Uruchom z wejściem na STDIN:
bejeweled.pl
:Łączy to jednokierunkowe rozwiązanie regex z obrotami
Wyjaśnienie:
W tym rozwiązaniu będę wielokrotnie obracać i wykonywać następujące 4 testy:
Gdzie
\C
jest „dowolny znak” (w przeciwieństwie do.
tego zawiera znak nowej linii). Tyle że\C
jest przestarzałe i prowadzi do ostrzeżeń, więc\H
zamiast tego używam (spacji poziome), co jest wystarczająco dobre, aby przechwycić wszystkie cyfry i znak nowej linii.Po 4 obrotach wykona wszystkie 16 niezbędnych testów
źródło
Python3, 314B
Zmień 8, 5 w linii 6 i 8s w linii 9, aby obsługiwać dowolnie duże rozmiary wejściowe; nie obchodzi też, jaka jest każda wartość, więc możesz ją karmić:
i wróci
yes
.Adnotacje
źródło
GNU sed 255 + 2 = 257B
Myślałem, że to nie będzie tak dobre jak Python, ale teraz: - / Dzisiaj nie miałem dostępu do Internetu, więc zająłem się rozwiązywaniem tego problemu w sed :). Musi zostać wywołany z opcją -r, tj.
sed -rf command.sed < input
Więc dodałem 2 do mojego wyniku.Jak to działa:
źródło
Ruby, 201 bajtów
Byłem rozczarowany, że nie widziałem żadnych rozwiązań tego wielkiego wyzwania, które nie używają wyrażenia regularnego ani brutalnej siły (chociaż są świetne), więc napisałem jedno. Wymaga wejścia na STDIN.
Podstawowy bitowy algorytm arytmetyczny pochodzi z tej fantastycznej odpowiedzi na Game Development Stack Exchange autorstwa @leander.
Ruby lambda, 181 bajtów
Tu jest jak lambda, które pobiera ciąg i powraca
true
albofalse
:Zobacz na repl.it: https://repl.it/ColJ/2
Nie golf i wyjaśnienia
Kod iteruje cyfry od „1” do „9.” Każda iteracja ma dwa odrębne kroki:
Pierwszym krokiem jest transformacja planszy, którą można zobaczyć w
s.scan(n)
bloku w niepoddanym golfie kodzie. Przekształca tablicę w tablicę 8 liczb całkowitych, po jednej dla każdego wiersza, traktując pasujące cyfry jako 1, a wszystkie pozostałe jako 0 w ciągu binarnym. Na przykład weź wiersz12231123
. W pierwszej iteracji stanie się to ciągiem binarnym10001100
(wszystkie 1-sza stają się - er, stay - 1s, a wszystkie inne cyfry stają się 0), co jest liczbą dziesiętną 140. W drugiej iteracji ten sam wiersz staje się01100010
(wszystkie 2s stają się 2s i wszystkie pozostałe cyfry stają się zerami) lub dziesiętnymi 98.Jednocześnie wykonuje drugą transformację, która jest taka sama jak pierwsza, ale z płytką obróconą o 90 stopni. To pozwala nam używać tej samej logiki do dopasowywania poziomego jak pionowego. Dla uproszczenia łączy dwie deski w jedną długą z zerą na początku, środkową (aby oddzielić dwie deski) i końcem do wypełnienia.
Drugim krokiem jest poszukiwanie możliwych dopasowań, które można zobaczyć w
each_cons(3).any?
bloku. Przekształcone wiersze (które są teraz 8-bitowymi liczbami całkowitymi) są rejestrowane w (nakładających się) grupach trzech wierszy ( x , y , z ) za pomocą arytmetyki bitowej. Każda grupa jest sprawdzana, aby sprawdzić, czy dopasowanie można wykonać w rzędzie y , poprzez przesunięcie elementu w rzędzie y lub przez przesunięcie elementu na y z x lub z . Ponieważ przed i za rzędami zarówno oryginalnej, jak i obróconej planszy występuje zerowy „rząd”, nie musimy sprawdzać, czy znajdujemy się w pierwszym czy ostatnim rzędzie planszy.Jeśli nie znaleziono żadnych dopasowań, przechodzi do następnej iteracji.
źródło