Czy ta tablica Kółko i krzyżyk jest ważna?


48

Wyzwanie

Biorąc pod uwagę grę w kółko i krzyżyk w dowolnym formacie, sprawdź, czy jest ważna, czy nie. Jeśli plansza może być wynikiem gry w kółko i krzyżyk, jest ważna. Na przykład ta tablica jest ważna:

XOX
OXO
XOX
Przeciwnie, ta tablica jest nieważna:

XXX
XXO
OOO

Wejście

  • Pełna (9/9) kółko i krzyżyk (wynik, nie gra).

Zasady

  • Format wejściowy musi umożliwiać przedstawienie wszystkich 512 możliwych kart wejściowych. Należy go określić wraz z instrukcjami, aby go utworzyć, jeśli jest niejasny / niejasny. Musisz jednak indywidualnie oznaczyć znaki planszy.
  • Możliwe są dwa wyjścia, jeden dla ważności i jeden dla inwalidztwa.
  • Możesz założyć, że na planszy nie ma pustych miejsc.

Przypadki testowe

Ważny:

XOX
OXO
XOX

XOX
XOX
OXO

XOO
OOX
OXX

OXO
XOX
OXO

Nieważny:

XXX
XXX
XXX

OOO
OOO
OOO

XXX
OOO
XXX

OOO
OOX
XXX

XXO
OXO
OOX

Mała pomoc?

Planszę uważa się za ważną (dla tego wyzwania) tylko wtedy, gdy spełnione są następujące dwa warunki:

  • Istnieje 5 X i 4 O lub 4 X i 5 O. Na przykład
    XXX
    OXO
    XXX
    jest uważany za nieprawidłowy, ponieważ istnieje 7 X i 2 Os.
  • Wygrał tylko gracz z 5 znakami lub żaden z nich nie wygrał. Na przykład,
    XXX
    OOO
    OOX
    jest uważany za niepoprawny, ponieważ albo rząd Os, albo rząd Xs zostaną utworzone jako pierwsze. Dwóch graczy nie może mieć swojej tury jednocześnie.

Obecny zwycięzca to ...

... galaretka odpowiada ais523 , w zadziwiającym 26 bajtów!


2
Być może dodaj także przykładowy przypadek testowy O O O X O X X O X, aby pokazać, że ten sam gracz może mieć zarówno rząd poziomy, jak i pionowy.
smls,

2
Musisz jednak indywidualnie oznaczyć znaki planszy. Nie jestem pewien, czy rozumiem tę część. Czy możesz podać kontrprzykład?
Arnauld,

3
@Tim X ma 4 znaki.
Martin Ender

2
@Sparr „Wygrał tylko gracz z 5 znakami lub żaden z nich nie wygrał”.
Martin Ender

2
@Kevin (Odpowiedz na pierwszy komentarz) Ponieważ żadna plansza z 9/9 nie zostanie ukończona, jeśli wygra drugi gracz (gracz z 4 znakami).
Erik the Outgolfer,

Odpowiedzi:


11

Galaretka , 26 bajtów

ṢŒrṪ4=$$Ðfx3ðœ-µẆm€6R¤;/µL

Wypróbuj online!

Format wejściowy jest trochę nietypowy; jest to ciąg reprezentujący tablicę, ale z nowymi liniami Windows (znak powrotu karetki i nowa linia). Na przykład XXO\r\nOXO\r\nOOX. (W rzeczywistości dowolny dwuznakowy ciąg dopełniania między wierszami działa, ale znaki nowej linii w systemie Windows są znacznie bardziej obronne niż inne opcje).

Podstawową ideą jest to, że szukamy znaków, które pojawiają się 4 razy na wejściu, ale nie mają trzech równomiernie rozmieszczonych wystąpień w oryginalnym ciągu. Z dwoma lub więcej znakami wypełnienia między liniami siatki 3 × 3, wszystkie linie poziome, pionowe i ukośne są równomiernie rozmieszczone, ale żadna inna równo rozmieszczona linia nie może mieć trzech elementów.

Wyjaśnienie:

ðI µS są separatory łańcuchowe , które rozszczepiają program na kilka części, z których każda niezależna. Zastąpiłem je spacjami poniżej, aby wszystko było trochę wyraźniejsze.

ṢŒrṪ4=$$Ðfx3 œ- Ẇm€6R¤;/ L
Ṣ                           sorted version of the input
 Œr                         run-length-encode it
        Ðf                  keep only elements where
   Ṫ                        delete the last element, and it was
    4=                      equal to 4
      $$                    parse Ṫ4= as a group
          x3                repeat each element three times

                Ẇ           all sublists of the input
                 m€         take every nth element of each (€) sublist
                   6R       for each n in 1..6
                     ¤      parse 6R as a group
                      ;/    flatten one level (m€ creates a nested structure)

             œ-             multiset difference
                         L  length of that difference

Innymi słowy, znajdujemy listę znaków, które pojawiają się dokładnie cztery razy na wejściu, i tworzymy listę składającą się z trzech kopii każdego z nich; znajdujemy listę wszystkich podsekwencji, które są równomiernie rozmieszczone w oryginalnym ciągu; a jeśli odejmiemy sekundę od pierwszej, chcemy, aby wynik miał długość 1 (tzn. gracz grał cztery razy, ale nie wygrał). Pamiętaj, że skoro jesteśmy na planszy 3 × 3 i każdy kwadrat jest pełny, obaj gracze nie mogą grać cztery razy. W Jelly 1 to prawda, 0 to falsey, więc nie musimy robić nic specjalnego, aby przekonwertować wynikową listę na wartość logiczną. (Jest µLto jednak wymagane, ponieważ w przeciwnym razie obie byłyby możliwe “XXX”i “OOO”byłyby prawdziwymi wartościami wyjściowymi, a pytanie wymaga, aby wszystkie prawidłowe płyty dały ten sam wynik).


3
To jest całkowicie czytelne.
pabrams,

21

JavaScript (ES6), 88 87 bajtów

s=>(a=[...s]).sort()[5]-a[3]&[7,56,73,84,146,273,292,448].every(j=>j&i,i=`0b`+s^~-a[4])

Zajmuje wejście jako ciąg 9 0i 1znaków i zwrotów 1za ważne, 0za nieprawidłowe. Sortujemy postacie w kolejności. Jeśli środkowe trzy postacie są teraz takie same, plansza jest nieważna, ponieważ jest ich zbyt wiele. W przeciwnym razie zamieniamy oryginalną tablicę na binarną, odwracając bity, jeśli jest więcej 0s niż 1s. W tym momencie tablica jest ważna, jeśli 0nie ma linii trzy, więc po prostu testujemy wszystkie osiem linii za pomocą tablicy mas bitowych. Edycja: Zapisano 1 bajt dzięki @ETHproductions.


@ETHproductions Ach, oczywiście wynik i tak będzie wynosił 0 lub 1.
Neil

14

Python 3, 131 127 125 100 96 bajtów

Dla innego podejścia algorytmicznego (i takiego, które naprawdę będzie pasować do tych wielobajtowych języków golfowych z wbudowaną kompresją), zamiast obliczać, czy tablica jest poprawna, uzyskajmy 512-bitową liczbę, gdzie każdy bit reprezentuje, czy nie określona tablica jest ważna lub nie i przekazuje wartość binarną reprezentującą tablicę. Ponadto, dzięki symetrii, drugą połowę tabeli można wyeliminować wraz z wiązką zer:

def z(b):return int('agqozfx67wwye6rxr508ch2i8qicekpreqkap0725pk',36)<<24&1<<b+(b>255)*(511-b-b)

Wartość testowa:

X X X
O X O
X X X

Jest reprezentowany jako wartość binarna 0b111010111, a funkcja zwraca wartość niezerową, jeśli tablica jest poprawna.


Usunięto zmienną pośrednią dla 4 mniej bajtów
Ken YN

Dwa bajty mniej, ponieważ a&(1<<b)nie wymagają nawiasów.
Ken YN

Wyrzucono 25 bajtów, używając symetrii, a jeszcze jeden, skracając 24 najniższe bity zerowe - musi być sposób na golfisty if b>255:b=511-b!
Ken YN

Znalazłem bardziej golfistyczny sposób na zrobienie tego if.
Ken YN

11

Partia, 140 bajtów

@set/aXXX=OOO=O=0
@for %%l in (%* %1%2%3 %1%4%7 %1%5%9 %2%5%8 %3%5%7 %3%6%9 %4%5%6 %7%8%9)do @set/a%%l+=1
@cmd/cset/a!XXX*!(O-=5)+!OOO*!~O

Pobiera dane wejściowe jako dziewięć osobnych argumentów i danych wyjściowych 1dla wiersza poprawnego i 0niepoprawnego. Działa poprzez śledzenie, ile razy widzi Olinię prostopadłą OOOlub XXX. Dogodnie Batch pozwala nam wykonywać arytmetykę liczb całkowitych pośrednio, więc nie zwiększamy, %%ltylko jakąś zmienną (chociaż interesują nas tylko trzy wymienione zmienne). Następnie musimy sprawdzić, czy albo Xnie wygrał i jest pięć Osekund, albo że Onie wygrał i są cztery Osekundy.


10

Mathematica, 82 75 bajtów

Dzięki Martin Ender za oszczędność 7 bajtów!

t=Total;3<(b=#~t~2)<6&&{t[c=If[b>4,1-#,#]],t/@c,Tr@c,Tr@Reverse@c}~FreeQ~3&

Nienazwana funkcja przyjmująca zagnieżdżoną 3 x 3 listę 1 i 0 jako dane wejściowe i wyjściowe Truelub False.

Używa poręcznej elastyczności Totalfunkcji (tutaj do gry w golfa t): biorąc pod uwagę przykładową tablicę e = { {1,2,3} , {4,5,6} , {7,8,9} }, polecenie t[e]sumuje trzy wektory (tutaj daje {12,15,18}); polecenie t/@esumuje każdą podlistę osobno (tutaj daje {6,15,24}); a polecenie e~t~2sumuje wszystkie dziewięć elementów (tutaj daje 45).

Najpierw sprawdzamy, 3<(b=#~t~2)<6czy całkowita liczba 1s wynosi 4 czy 5; jeśli nie, wychodzimy z False. Jeśli tak, używamy, c=If[b>4,1-#,#]aby wymusić, aby były cztery 1, a nie pięć. Następnie obliczamy sumy kolumn, sumy t[c]wierszy t/@c, sumę głównej przekątnej Tr@ci sumę przeciwnej przekątnej Tr@Reverse~c, i używamy ~FreeQ~3do sprawdzenia, czy 3nie pojawia się na żadnym poziomie w tych obliczonych sumach.

Zabawna uwaga dodatkowa: w przeciwieństwie do większości wyglądów na tej stronie, tutaj Trnie używa się jej do podsumowania jednowymiarowej listy, ale jest ona faktycznie używana zgodnie z przeznaczeniem - do obliczania śladu macierzy dwuwymiarowej!



5

JavaScript (ES6), 101 bajtów

Pobiera dane wejściowe jako 9-bitową maskę binarną, gdzie X = 1i O = 0(MSB = lewa górna komórka, LSB = prawa dolna komórka).

n=>[7,56,73,84,146,273,292,448,o=x=0].map((m,i)=>(c-=n>>i&1,m&n^m?m&n||o++:m&&x++),c=4)&&!(c|x&&~c|o)

Przypadki testowe


Wiedziałem, że musi istnieć (nieco) proste rozwiązanie bitowe.
Dobra

5

Python 2, 158 132 109 92 91 123 bajty

def v(b):f=sum(b,());w={x[0]for x in b+zip(*b)+[f[::4],f[-3:1:-2]]if len(set(x))==1};return sum(map(`b`.count,w))==len(w)*5

Dane wejściowe to lista / krotka wierszy, z których każda to trzy krotka ciągów znaków, np .:
[('X', 'O', 'X'), ('O', 'X', 'O'), ('X', 'O', 'X')]

Zapisano niektóre bajty, ignorując przekątne w odpowiedzi @ Maltysen, co również skróciło poniższe wyrażenie.

Dzięki @vaultah za uratowanie 17 18 bajtów.

Konieczne okazuje się sprawdzenie przekątnych, które usunęły wiele powyższych oszczędności.

Wypróbuj tutaj.

Wyjaśnienie

def v(b):
  f=sum(b,())
  w={x[0]for x in b+zip(*b)+[f[::4],f[-3:1:-2]]if len(set(x))==1}
  return sum(map(`b`.count,w))==len(w)*5

fto spłaszczony wkład do krojenia.
wzawiera postacie z wygrywającymi sekwencjami.
Policz wystąpienia każdej zwycięskiej postaci, która będzie wynosić 0, jeśli wjest pusta, lub 5, jeśli len(w)wynosi 1. 10 sum, gdy obie mają zwycięską sekwencję, jest niemożliwe. Zwycięzca posiadający 5 oznacza, że ​​przegrany ma 4. Nie możesz mieć> 5 bez zwycięskiej sekwencji.


lambda b:len({x[0]for x in b+zip(*b)if len(set(x))==1})<2and set(map(b.count,'XO'))=={4,5} zapisuje niektóre bajty.
vaultah 12.12.16

i właśnie zauważyłem, że ...and{4,5}==set(map(b.count,'XO')) zapisuje jeszcze jeden bajt.
vaultah 12.12.16

Myślę, że to błędnie uznaje ostatni „nieprawidłowy” przykład z pytania za prawidłowy, ponieważ nie gwarantuje, że zwycięzcą jest gracz z 5 znakami.
smls,

@smls Masz rację. Sprawdzenie tego warunku kosztuje dużo bajtów, być może można go zagrać w golfa dalej.
Jake Cobb,

5

R, 88 82 bajtów

x=scan();`if`(sum(x)%in%4:5,all(apply(combn(which(x==(sum(x)<5)),3),2,sum)!=15),F)

Wszystkie kombinacje trzech liczb całkowitych od 1 do 9, które sumują się do 15, to rzędy / kolumny / przekątne kwadratu pokazanego poniżej.

2 7 6
9 5 1
4 3 8

Funkcja przyjmuje dane wejściowe jako wektor wartości logicznych, T dla „X”, F dla „O”, która jest spłaszczoną reprezentacją planszy. ALE, są one ponownie uporządkowane, tak aby ich indeks był taki sam jak liczba w kwadracie, w kolejności (2,7,6,9,5,1,4,3,8). Kolejność ta może zostać osiągnięta przez spłaszczenie planszy w normalny sposób, a następnie pocięcie o c (6,1,8,7,5,3,2,9,4). Więc to

X O X
O X O
X O X

jest reprezentowany jako:

c(T, F, T, F, T, F, T, F, T)[c(6,1,8,7,5,3,2,9,4)]

który jest:

c(F, T, F, T, T, T, F, T, F)

Funkcja najpierw określa, czy jest gracz z dokładnie czterema znakami. Jeśli tak, funkcja używa faktów, które sumują do 15, aby ustalić, czy ten gracz ma trzy z rzędu (plansza jest nieprawidłowa, jeśli gracz ma).

Jeśli chcesz wziąć tradycyjnie spłaszczoną płytkę jako kod wejściowy, kod wyglądałby następująco:

f=function(x)ifelse(sum(x)%in%4:5,all(apply(combn(c(2,7,6,9,5,1,4,3,8)[which(x==(sum(x)<5))],3),2,sum)!=15),F)

Jestem w tym nowy, porady będą mile widziane.


1
Zapisz 2 bajty, jeśli if()zamiast tego używasz : f=function(x)if (sum(x)%in%4:5,all(apply(combn(which(x==(sum(x)<5)),3),2,sum)!=15),F). Nie są dokładnie testowane. Backticks niszczy kod, ale tak jest backtick if backtick(.
Jonathan Carroll

1
Jeszcze lepiej; x=scan();if (sum(x)%in%4:5,all(apply(combn(which(x==(sum(x)<5)),3),2,sum)!=15),F)i wprowadź jako 1i 0. 82 bajty.
Jonathan Carroll

3

JavaScript (ES6), 145 139 131 127 bajtów

s=>!(q="XO"[s.split`O`.length-5])|![...s].some((c,i)=>c==q&!/(.)(\1|..(\1|.(\1|.\1.).)..)\1/.test(s.slice(0,i)+0+s.slice(i+1)))

Wprowadź jako ciąg rozdzielany spacjami, taki jak "XOX OXO XOX". Wyjścia 1dla nieprawidłowej płyty, 0dla prawidłowej. To oczywiście nie jest najlepsza technika, przynajmniej nie w JavaScript ...

Zasadniczo sprawdza, czy oba następujące elementy są wstrzymane:

  • Jest dokładnie 4 lub 5 O s, AND
  • istnieje co najmniej jeden z 5-elementowych elementów, który po usunięciu tworzy niezdecydowaną grę.

Wyrażenie regularne polega na sprawdzeniu, czy decyzja została podjęta. Pasuje do planszy, jeśli istnieją dowolne odcinki o długości trzy jednego znaku z 0 (wiersz), 2 (dolna prawa przekątna), 3 (kolumna) lub 4 (dolna lewa przekątna) znaki oddzielające każdą parę.

Testowy fragment kodu


2

Rubin, 104 99 91 bajtów

->x{[7,56,448,292,146,73,84,273].none?{|y|b=x.to_i 2;((a=x.count'1')==4?b:a==5?~b:7)&y==y}}

Format wejściowy: ciąg binarny zawierający 9 symboli (0 i 1s) reprezentujących tablicę, na przykład pierwszy przypadek testowy 101010101. Najpierw przekonwertuj go na liczbę binarną, sprawdź, czy popcount wynosi 4 lub 5, jeśli 5 to odwróć liczbę, abyśmy zawsze mieli 4. Sprawdź, czy trzy z nich są wyrównane (maskujące poziomo, pionowo, po przekątnej).

TL; DR : Zwraca false, jeśli gracz z 4 znakami wygrał, prawda w przeciwnym razie.

Dzięki Jordan za komentarze,

Nie mogę odtworzyć łańcucha UTF-8, który zapisałby kolejny bajt.


Można wymienić .select{...}[0]z .find{...}.
Jordan

I możesz zaoszczędzić jeszcze jeden bajt, zastępując tablicę liczb "8ǀĤITđ".unpack("U*")(na wypadek, gdyby coś zginęło w tłumaczeniu, łańcuch jest wynikiem wywołania pack("U*")oryginalnej tablicy; ma 12 bajtów).
Jordan

czy mógłbyś użyć any?zamiast none?przerzucania wyjścia i zapisywania całego bajtu?
Alexis Andersen

Próbowałem z jednym? zamiast żadnego? ale potem potrzebuję! odwrócić wyjście.
GB

1

Perl 6 , 103 99 bajtów

{my \c=%(.flat.Bag.invert)<5>;?all c,|(.[0]===c if [eq] $_ for |.flat[<0 4 8>,<2 4 6>],|$_,|.&zip)}

Lambda, która akceptuje listę takich jak (('X','O','X'), ('O','X','O'), ('X','O','X')) i zwraca Bool.

Działa to tak:

  1. Sprawdź, który znak pojawia się dokładnie 5 razy i zapisz go c. (Jeśli żaden znak nie pojawi się dokładnie 5 razy, będzie on zawierał wartość fałszu)
  2. Iteruj po wszystkich przekątnych, wierszach i kolumnach i odfiltruj te „wygrywające” (tj. Te, w których wszystkie trzy litery są równe) .
  3. Sprawdź, czy cjest prawdą, a każda wygrywająca linia jest typu c.

1

PHP, 125 bajtów

for($p=$n=$argv[1];$p;$p/=2)$i+=$p&1;foreach([7,56,448,73,146,292,273,84]as$m)$n&$m^$m?$n&$m||$o++:$x++;echo!$x|!$o&&2>$i^=4;

Miałem taki sam pomysł jak Arnauld : Płyta jest ważna, jeśli są ustawione 4 lub 5 bitów i albo XalboO albo nikt nie ma passę (ale nie jednocześnie).

Aby wygenerować sygnał z pola zastępuje Xsię 1i Oz0 , dołącz linie i przekonwertować plik binarny do przecinku podać jako argument wiersza poleceń.

wydruki są 1ważne; puste wyjście dla niepoprawnego. Uruchom z -r.

awaria

// count set bits
for($p=$n=$argv[1];$p;$p/=2)$i+=$p&1;
    /* ($p/=2 takes longer than $p>>=1, but eventually
       $p will come close enough to 0 for the loop to finish */
// count streaks for X and O
foreach([7,56,448,73,146,292,273,84]as$m)
    $n&$m^$m            // ($n masked with streak)!=streak <=> no streak for X
        ?$n&$m||$o++    // true: O has a streak if ($n masked with streak) is empty
        :$x++;          // false: X has a streak
echo!$x|!$o&&2>$i^=4;   // valid if not both have a streak
                        // AND $i is 4 or 5 (toggle 4 -> result 0 or 1)

1

Szybki, 178 bajtów

func t(i:String)->Bool{let r=i.characters.filter({$0=="X"}).count;let g=i.characters.split(separator:"\n").map(String.init).contains;return(r==5||r==4)&&(!g("XXX") && !g("OOO"))}

0

ES6 (Javacript), 130, 138, 117 bajtów

EDYCJE:

  • 21 bajtów off dzięki doskonałej porady @Neil!
  • Początkowa wersja była podatna na błąd, który należy teraz naprawić kosztem +8 bajtów. (Dzięki @ETHproductions za wskazanie tego)

Niezwykle proste podejście. Prawdopodobnie można grać w golfa nieco dalej.

Akceptuje dane wejściowe jako 9 oddzielnych argumentów, 1es i 0es

  • 1 jest dla X
  • 0 oznacza O

Argumenty: 1-3 - pierwszy rząd, 4-6 - drugi rząd, 7-9 - trzeci rząd.

Grał w golfa

(a,b,c,d,e,f,g,h,j)=>![a+b+c,d+e+f,g+h+j,a+d+g,b+e+h,c+f+j,a+e+j,g+e+c,7].some(x=>x=="7777307777"[a+b+c+d+e+f+g+h+j])

Interaktywne „łóżko testowe”

var a=b=c=d=e=f=g=h=j=0;

T=(a,b,c,d,e,f,g,h,j)=>![a+b+c,d+e+f,g+h+j,a+d+g,b+e+h,c+f+j,a+e+j,g+e+c,7].some(x=>x=="7777307777"[a+b+c+d+e+f+g+h+j]);

function test() {
  if(T(a,b,c,d,e,f,g,h,j)) {
     grid.style.backgroundColor='green';
     msg.innerHTML="GOOD"
  } else {
     grid.style.backgroundColor='red';
     msg.innerHTML="BAD"
  }
}
<table id=grid style="background: red">
<thead>
  <tr>
     <td id=msg align="center" colspan="3">BAD</td>
    </tr>
  </thead>
  <tr>
      <td><input type="checkbox" onchange="a=this.checked*1;test();" id="ca"/></td>
      <td><input type="checkbox" onchange="b=this.checked*1;test();" id="cb"/></td>
      <td><input type="checkbox" onchange="c=this.checked*1;test();" id="cc"/></td>
    </tr>
    <tr>
      <td><input type="checkbox" onchange="d=this.checked*1;test();" id="cd"/></td>
      <td><input type="checkbox" onchange="e=this.checked*1;test();" id="ce"/></td>
      <td><input type="checkbox" onchange="f=this.checked*1;test();" id="cf"/></td>
    </tr>
    <tr>
      <td><input type="checkbox" onchange="g=this.checked*1;test();" id="cg"/></td>
      <td><input type="checkbox" onchange="h=this.checked*1;test();" id="ch"/></td>
      <td><input type="checkbox" onchange="j=this.checked*1;test();" id="cj"/></td>
    </tr>
 </table>


Mogę się mylić, ale wygląda na to, że to tylko sprawdza, czy jest zwycięzca. Ważna tablica nie może mieć zwycięzcy; na przykład [1,0,1,1,0,1,0,1,0]( XOX XOX OXO).
ETHproductions

Tak, zgubiłem negację podczas gry w golfa. Ma sprawdzić, czy przeciwna strona nie jest zwycięzcą. Powinien zostać teraz naprawiony. Dzięki !
zeppelin,

(Zacząłem komentować przed ostatnią edycją) Czy możesz a) pisać a+b+c+d+e+f+g+H+izamiast F.reduce((r,c)=>r+=c*1)(w którym momencie nie potrzebujesz F) b) pisać .includes(C)(i przejść do wartości inline C)?
Neil,

@Neil, to prawdopodobnie zadziała, spróbuję jutro. Dzięki !
zeppelin,

Czy OOO XXX OXOporażka?
Ismael Miguel,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.