Podłącz Four Validator

20

Wprowadzenie

Connect Four to gra, w której próbujesz zdobyć cztery z rzędu: poziomo, pionowo lub po przekątnej. W tym golfie próbujemy dowiedzieć się, kto wygrał, biorąc pod uwagę planszę. Zawsze będzie jeden zwycięzca i tylko jeden zwycięzca.


Zadanie

Biorąc pod uwagę tablicę Connect Four, dowiedz się, kto wygrał: Xlub Y. Zawsze będzie jeden zwycięzca i tylko jeden zwycięzca. Rozmiar planszy będzie zawsze wynosił 6 na 7, podobnie jak plansza na zdjęciu.

Biorąc pod uwagę tablicę, następująca tablica, w tym przypadku, Xjest czerwona i Yniebieska:

wprowadź opis zdjęcia tutaj

Twój wkład to:

OOOOOOO
OOOOOOO
OOOOOOO
OOOOXOO
OOOXXOO
OOXYYYY

Możesz rozdzielić rzędy gry według znaku nowej linii (jak wyżej), bez dzielenia znaku, podzielić rzędy na tablicę lub listę, lub możesz wprowadzić matrycę znaków.

Prawidłowe dane wyjściowe dla tego przykładu:

Y

Y ma cztery z rzędu; więc Y jest zwycięzcą. Wyprowadzamy więc Y.


Przypadki testowe

Wkład:

OOOOOOO
OOOOOOO
OOOOOOO
OOOOOOO
OOYYOOO
OYXXXXO

Wynik:

X

Wkład:

OOOOOOO
OOOOOOO
OOOOOOO
XXXXOOO
YXYYOOO
YXYYXYX

Wynik:

X

Wkład:

YXYYXOO
XYXXYOO
XXXYYOO
YYYXXOO
XXYYYYO
XXYYXXO

Wynik:

Y

Wkład:

OOOOOOO
OOOOOOO
OYOOOOO
OOYOOOO
OOOYOOO
OOOOYOO

Wynik:

Y

Wkład:

OOOOOOO
OOOOOOO
OYOOOOX
OOYOOOX
OOOXOOX
OXOXYOX

Wynik:

X

Punktacja

Najmniej wygranych bajtów!

Neil
źródło
To idealne wyzwanie dla PMA / Snails codegolf.stackexchange.com/questions/47311/…
Jerry Jeremiah
2
Czy możemy założyć, że zwycięzca zawsze będzie miał jeszcze jeden token niż przegrany?
ćpun matematyki
1
@mathjunkie Myliłem się, nie możesz tego założyć.
Neil
3
@nfnneil, czy wynik musi być X lub Y, czy też możemy wybrać dwa inne spójne wyniki, aby wskazać zwycięzcę?
Martin Ender
1
Czy możemy użyć innych znaków jako danych wejściowych? Lub wprowadzić matrycę numeryczną?
Luis Mendo,

Odpowiedzi:

2

Galaretka , 19 bajtów

UŒD;ŒD;Z;ṡ€4;/ṢEÞṪṪ

Wypróbuj online!

Trzon tej odpowiedzi został skopiowany mojej odpowiedzi na to bardzo podobne pytanie .

Wyjaśnienie

UŒD;ŒD;Z;ṡ€4;/ṢEÞṪṪ
   ;  ; ;             Append {the input} and the following three values:
UŒD                     the antidiagonals of {the input};
    ŒD                  the diagonals of {the input};
       Z                the transposed {input}.
         ṡ 4          Find all length-4 substrings
          €             of each subarray within that.
            ;/        Flatten one level.
                Þ     Sort, with the following sort order:
               E        If all elements are the same, sort later.
              Ṣ         Tiebreak via lexicographical order.
                 ṪṪ   Take the last element of the last element.

Całkiem proste: bierzemy wszystkie rzędy, kolumny, przekątne i antydiagonale (tak jak w walidatorze n-królowych), następnie bierzemy wszystkie podłańcuchy długości 4, a następnie sortujemy je w taki sposób, aby zwycięska linia 4 sortowała się do koniec. (Potrzebujemy rozstrzygnięcia w przypadku, gdy istnieje OOOOdodatek do XXXXlub YYYY.) Weź ostatni element ostatniego elementu, i będzie on Xlub Yzgodnie z wymaganiami.


źródło
6

Siatkówka, 51 48 bajtów

Podziękowania dla Martina Endera za oszczędność 3 bajtów

M`X((.{6}X){3}|(.{8}X){3}|(.{7}X){3}|XXX)
T`d`YX

Wypróbuj online!

Pobiera dane wejściowe jako listę wierszy oddzieloną przecinkami

ćpun matematyki
źródło
Możesz zaoszczędzić kilka bajtów, używając etapu dopasowania i skracając (.{7}X){3}|XXXdo (.{7}X|X)\4\4: tio.run/nexus/retina#fc4xCsMwDAXQPfcI2GC6NDS5QaeipcP/…
Martin Ender
1
@MartinEnder Nie widzę, jak możesz użyć \4- chcesz powtórzyć efekt .{7}nie pasującego łańcucha. (A równoważenie grup prawdopodobnie byłoby zbyt długie).
Neil
1
@ Nee o tak, nieważne, jakoś nie pomyślałem, że istnieją inne komórki OXY niż dopasowanie w siatce. użycie etapu dopasowania nadal oszczędza 3 bajty.
Martin Ender
5

JavaScript (ES6), 54 55

Edytuj 1 bajt zapisany dzięki @Arnauld

Sprawdzam tylko, czy X jest zwycięzcą, ponieważ zawsze będzie jeden zwycięzca i tylko jeden zwycięzca

Dane wejściowe to ciąg znaków z dowolnym separatorem, jak w odpowiedzi @ Arnauld

F=    
b=>'YX'[+[0,6,7,8].some(x=>b.match(`X(.{${x}}X){3}`))]

;['OOOOOOO OOOOOOO OOXOOOO OOXOOOO OOXOOOO OOXOYYY'
 ,'OOOOOOO OOOOOOO OOXOOOO OOYXOOO OOYOXOO OOYYOXY'
 ,'OOOOOOO,OOOOOOO,OOOOOOO,OOOOOOO,OOYYOOO,OYXXXXO'
 ,'OOOOOOO,OOOOOOO,OOOOOOO,XXXXOOO,YXYYOOO,YXYYXYX'
 ,'YXYYXOO,XYXXYOO,XXXYYOO,YYYXXOO,XXYYYYO,XXYYXXO']
.forEach(s => console.log(s,F(s)))

edc65
źródło
@Arnauld racja, dzięki
edc65
4

Galaretka , 25 22 bajtów

ŒgL⁼¥Ðf
;UŒD€;Z;$ç€4FṀ

Pobiera listę ciągów (lub listy listy znaków) utworzonych z X, YiO (działałby również z zamianami, dzięki czemu spacja ma niższą liczbę porządkową niż oba liczniki).

Wypróbuj online! lub uruchom rozszerzoną wersję, która pobiera ciąg wielowierszowy.

W jaki sposób?

ŒgL⁼¥Ðf - Link 1, runs of given length: list A, length B  e.g. "XYYYXXO", 4
Œg      - group runs of equal elements of A                     ["X","YYY","XX","O"]
     Ðf - filter keep:
    ¥   -     last two links as a dyad:
  L     -         length                                         1   3     2    1
   ⁼    -         equal to B?         (none kept in this case->) 0   0     0    0

;UŒD€;Z;$ç€4FṀ - Main link: list of list of chars (or list of stings) I
 U             - reverse each row of I
;              - I concatenated with that
  ŒD€          - positive diagonals of €ach (positive and negative diagonals)
        $      - last two links as a monad:
      Z        -     transpose of I (i.e. the columns)
       ;       -     concatenated with I (columns + rows)
     ;         - concatenate (all the required directional slices)
         ç€4   - call the last link (1) as a dyad for €ach with right argument = 4
            F  - flatten the result
             Ṁ - take the maximum ('Y'>'X'>'O') - this has the bonus effect of returning:
                               'Y' or 'X' for a winning board; and
                               'O' or '' for a (valid) game in progress.
Jonathan Allan
źródło
4

JavaScript (ES6), 77 76 69 bajtów

Zaoszczędzono 7 bajtów dzięki Neilowi

Pobiera dane wejściowe jako ciąg oddzielony od czegoś , w którym coś jest w zasadzie dowolnym znakiem.

b=>[...'XXXXYYYY'].find((c,i)=>b.match(`(${c}.{${(i%4+6)%9}}){3}`+c))

Przypadki testowe

Arnauld
źródło
Dlaczego nie użyć b.match()? Powinieneś oszczędzić na RegExppołączeniu.
Neil
@Neil Zupełnie zapomniałem, że dokonałem match()niejawnej konwersji na RegExp. Dzięki!
Arnauld
3

Python 2 , 143 bajty

m=input()
u=[r[::-1]for r in m]
print"YX"[any(any('X'*4in''.join(t[i][j-i]for i in range(j+1))for j in range(6))for t in(m[::-1],m,u,u[::-1]))]

Pobiera listę ciągów znaków lub listę znaków. Na stałe zakodowane dla 6 wierszy po 7 kolumn, jak gwarantuje specyfikacja.

Wypróbuj online!

Jonathan Allan
źródło
2

PHP, 71 bajtów

echo preg_match('#X(XXX|(.{8}X){3}|(.{7}X){3}|(.{9}X){3})#',$argn)?X:Y;

Wersja online

Jörg Hülsermann
źródło
2

Python 2 , 201 143 129 128 107 bajtów

Postanowiłem dodać razem poziome, pionowe i przekątne do jednej listy, a następnie dodać przyrost, a następnie poszukać X na nim razy. A ponieważ zawsze będzie zwycięzca, mogę założyć, że wygrał Y, jeśli X nie. Kody te obejmują macierz wszystkich różnych elementów i pustych miejsc.

lambda m:"YX"[any("X"*4in"".join(a)for a in zip(*m)+m+zip(*["0"*(7-i)+m[i]+"00"*i+m[i]for i in range(6)]))]

Wypróbuj online!

Kredyty

  • Od 129 do 107 bajtów tylko przez ASCII .
Neil
źródło
Samo-odpowiedź jest całkowicie do przyjęcia.
Jonathan Allan
Nie patrząc na to zbyt dużo, nie wydaje się być zbędne spacje pod adresem: i:] for, i, r, r] fori 1 for.
Yytsi
@TuukkaX Dziękujemy za dane wejściowe, zaktualizowane.
Neil
Również *(len(m)-1)może być *~-len(m). Jak to działa.
Yytsi
] forI 1 forsą nadal.
Yytsi
1

K (ngn / k) , 58 55 bajtów

{"XY"@|/&/'88<x ./:/:,/{x+/:/:+3+[4#1-+!3 3]\&4}'+!6 7}

Wypróbuj online!

{ } funkcja z argumentem x

+!6 7 wszystkie możliwe pary 0..5 i 0..6

{ }' dla każdego z nich

4#1-+!3 3 to 4 z 8 kierunków prostopadłych: (1 1;1 0;1 -1;0 1)

3+[ ]\&4zacznij od listy czterech zer ( &4) i wykonaj 3 kroki w każdym z kierunków

x+/:/: zacznij od każdej możliwej pozycji i wykonaj kroki w każdym możliwym kierunku

,/powiązać. w tym momencie mamy macierz 4-list par współrzędnych, niektóre z nich wystają poza planszę

x ./:/: wyszukaj odpowiednie komórki z x

88<które z nich są "Y"? (88 to kod ASCII "X")

&/'które 4-listy składają się tylko z "Y"-s? (i-redukuj-każdy)

|/czy jest co najmniej jeden taki? (lub zmniejsz)

"XY"@jeśli fałszywy zwrot "X", jeśli prawdziwy zwrot"Y"

ngn
źródło
1

Zsh , 207 ... 159 bajtów

Historia wersji: 4 iteracje dla ~ 25 bajtów w pierwszym tygodniu; następnie 3 kolejne iteracje dla ~ 25 bajtów 6 miesięcy później.

t(){a=($^a-$^@_);for s l (${w:^^argv})s+=$l&&for ((i=0;i++<$#s;))a[i]+=$s[i];}
w=(+)
t $@
for s;w[++j]=${(l:j:)}_
t $@
t ${(Oa)@}
[[ $a = *XXXX* ]]&&<<<X||<<<Y

( pierwszy ) ( drugi ) ( trzeci ) ( czwarty ) ( piąty ) ( szósty ) Wypróbuj online!

W stopce wypisuję zarówno tablicę wejściową, jak i tablicę, którą budujemy z niej do stderr. Przewiń w dół, aby je debugować, aby je zobaczyć. Tablica, którą budujemy, jest teraz znacznie dłuższa, ponieważ trobi kartezjański produkt z płytką wejściową przy każdym wywołaniu. (Hej, to skróciło kod o kilka bajtów.)

Jest tu wiele do omówienia, więc przeniosłem komentarze (wydanie szóste) na adnotacje .

(tl; dr: konkatenuj transpozycje oryginalnej tablicy, ale pamiętaj o ich oddzieleniu)

Funkcja Gamma
źródło