Zdobywanie punktów w Go to zadanie, które nie jest wcale takie łatwe. W przeszłości odbyło się kilka debat na temat projektowania reguł obejmujących wszystkie dziwne przypadki narożne, które mogą się zdarzyć. Na szczęście w tym zadaniu nie musisz robić skomplikowanych czynności, takich jak życie i śmierć czy wykrywanie seki. W tym zadaniu musisz wdrożyć program oceniający grę zgodnie z zasadami Tromp-Taylor bez Komi.
Procedura punktacji jest dość prosta:
punkt P, niebędący kolorem C, mówi się, że osiąga C, jeśli istnieje ścieżka (w pionie lub w poziomie) sąsiadujących punktów koloru P od P do punktu koloru C.
Wynik gracza to liczba punktów jego koloru , plus liczba pustych punktów, które osiągają tylko jej kolor.
Na przykład rozważmy następującą tablicę. X
, O
I -
oznaczają czarny, biały i bezbarwnego krzyżakowe
- - - X - O - - -
- - - X - O - - -
- - - X - O - - -
- - - X O - - O -
X X X O - O O - -
- - - X O - - O O
- - - X - O - - -
- - - X - O - X -
- - - - - O - - -
Zastosowanie reguły punktacji daje następujący wynik. x
, o
i -
reprezentują bezbarwne skrzyżowania, które są liczone jako czarne, białe i niczyje.
x x x X - O o o o
x x x X - O o o o
x x x X - O o o o
x x x X O o o O o
X X X O o O O o o
- - - X O - - O O
- - - X - O - - -
- - - X - O - X -
- - - - - O - - -
Zgodnie ze schematem czarny ma 23 punkty, biały ma 29 punktów terytorium. Dlatego twój program powinien wydrukować W+6
dla tej płyty.
Mam nadzieję, że w ten sposób będzie wystarczająco jasne.
Wejście i wyjście
Wejście jest ciąg znaków, który zawiera dokładnie n² znaków X
, O
, -
gdzie n nie jest znany w czasie kompilacji. Twój program powinien zignorować wszystkie inne znaki w strumieniu wejściowym. Zachowanie jest niezdefiniowane, jeśli nie ma liczby całkowitej n takiej, że liczba XO-
znaków jest równa n² . Możesz założyć, że n jest w [0, 255] .
Sekwencję znaków należy interpretować jako tablicę składającą się z n rzędów i kolumn. Wynik jest wartością bezwzględną różnicy całkowitej liczby punktów bieli i czerni w ujęciu dziesiętnym. Jeśli biały ma więcej punktów, jest poprzedzony przez W+
, jeśli czarny ma więcej punktów, jest poprzedzony przez B+
. W przypadku, gdy obaj gracze mają taką samą liczbę punktów, wynik jest Jigo
.
Dane wejściowe należy czytać w sposób zdefiniowany w implementacji. Dane wejściowe mogą nie być częścią kodu źródłowego.
Warunki wygranej
To jest golf golfowy. Obowiązują zwykłe konwencje gry w golfa. Zgłoszenie z najmniejszą liczbą znaków w źródle wygrywa. Tylko programy, które w pełni implementują specyfikację, mogą wygrać.
Przypadki testowe
Wkład:
- - - X - O - - -
- - - X - O - - -
- - - X - O - - -
- - - X O - - O -
X X X O - O O - -
- - - X O - - O O
- - - X - O - - -
- - - X - O - X -
- - - - - O - - -
Wydajność: W+6
Wkład:
Xavier is insane -- says Oliver
Wydajność: Jigo
Inpout:
Code-Golf
Wydajność: Jigo
Wkład:
-XXXXXXX-XOOOOOOOXXO-OXXXOXXXOX--XOXXOOX
-
XOOXXOX--XOXXXOXXXO-OXXOOOOOOOX-XXXXXXX-
Wydajność: B+21
Wkład:
- - X O O O O X X - - - - - - X O O -
- X X O X O X X O X X X X X X - X O -
- X O O X X X - O O O X O O X X X O -
- X O O O X X O O O O O O X X X O - -
- - X X O X - X X X X O O O O O O O -
- - X O O X X X - X X X O O O X X O -
- - X O - O X O X O O O O O X X X O -
- X O O - O O O X X X X X O O X O - -
- X X X O - - - O X O X X X O X O - -
X O O O O - - O - O O O O X X X O O -
X X O - - - O - - O O X X - - X X O O
X O O O - - O - O O X - - - - X O O X
- X X X O O X O O X X - - - - X X X X
X - X X X O X X O O X - - X X O X O O
X X O O X O X O X X - - - X O O O O -
X O - O X X X O X - - - - - X O - - -
O O - O X O O O O X X - X X X X O - -
O O - O O O X O X X - - X - X X O - -
- - O - - O X X X - - - - X O O O - -
Wydajność: B+6
Więcej przypadków testowych już wkrótce.
wdrożenie referencyjne
Utworzyłem implementację referencyjną napisaną w ANSI C. Ta implementacja odczytuje dane wejściowe ze standardowego wejścia i zapisuje dane wyjściowe na standardowe dane wyjściowe.
/* http://codegolf.stackexchange.com/q/6693/134
* reference implementation
* by user FUZxxl
*/
#include <stdio.h>
#include <stdlib.h>
#define MAXBOARD 256
/* bit 0x01: black colour
* bit 0x02: white colour
* bit 0x04: there is a stone on the intersection
*/
enum colour {
UNCOLOURED = 0x0,
BLACK_REACHED = 0x1,
WHITE_REACHED = 0x2,
BOTH_REACHED = 0x3,
HAS_STONE = 0x4,
BLACK = 0x5,
WHITE = 0x6
};
static enum colour board[MAXBOARD * MAXBOARD] = { 0 };
static int bsize = 0;
static void read_input(void);
static void fill_board(void);
static void show_score(void);
int main()
{
read_input();
fill_board();
show_score();
return EXIT_SUCCESS;
}
static void read_input(void)
{
int n = 0;
int invalue;
while ((invalue = getchar()) != EOF) {
switch (invalue) {
case '-': board[n++] = UNCOLOURED; break;
case 'X': board[n++] = BLACK; break;
case 'O': board[n++] = WHITE; break;
}
}
while (bsize * bsize < n) bsize++;
/* your program may exhibit undefined behaviour if this is true */
if (bsize * bsize != n) exit(EXIT_FAILURE);
}
static void fill_board(void)
{
int i,j;
int changes;
enum colour here, top, bottom, left, right, accum;
do {
changes = 0;
for (i = 0; i < bsize; ++i) {
for (j = 0; j < bsize; ++j) {
here = board[i * bsize + j];
if (here >= BOTH_REACHED) continue;
top = i == 0 ? UNCOLOURED : board[(i - 1) * bsize + j];
left = j == 0 ? UNCOLOURED : board[i * bsize + j - 1];
bottom = i == bsize-1 ? UNCOLOURED : board[(i + 1) * bsize + j];
right = j == bsize-1 ? UNCOLOURED : board[i * bsize + j + 1];
accum = here | top | bottom | left | right;
accum &= ~HAS_STONE;
changes |= board[i * bsize + j] != accum;
board[i * bsize + j] = accum;
}
}
} while (changes);
}
static void show_score(void) {
int w = 0, b = 0, n;
for (n = 0; n < bsize*bsize; ++n) switch (board[n] & ~HAS_STONE) {
case BLACK_REACHED: ++b; break;
case WHITE_REACHED: ++w; break;
}
if (b != w)
printf("%s%i\n",b>w?"B+":"W+",abs(b-w));
else
printf("Jigo\n");
}
źródło
W+7
?S+
to literówka (ponieważ wcześniej wymieniłeś możliwe wyjście jako alboW+
,B+
alboJigo
) i spojrzałem na klawiaturę i zobaczyłem, żeS
jest bliskoW
... A może używasz Dvoraka?Odpowiedzi:
GolfScript (105 bajtów)
Demo online .
Wypełnienie zalane na podstawie mojej wcześniejszej odpowiedzi .
Rozwiązanie wypełnia jedną kopię oryginalnej płyty X, a drugą O. W ten sposób puste komórki, które są osiągalne za pomocą obu kolorów, są oceniane dla obu, ale anulują odejmowanie.
źródło
C (
438434413382364336322298294292290 znaków)Wszystkie nowe wiersze oprócz pierwszego wstawiono w celu zwiększenia czytelności. Skomentowana i nieco bardziej czytelna wersja znajduje się tutaj .
Ta odpowiedź jest zasadniczo rozwiązaniem referencyjnym, ale zawiera wszystkie te bezużyteczne rzeczy (takie jak typy [kto i tak potrzebuje czegoś innego
int
?] I zgodność ze standardami [wartość zwracana z głównego? Proszę!])Poprawki i ulepszenia
438 → 434
Porzuciłem jawną inicjalizację zmiennych po tym, jak przekonałem się, że są one automatycznie inicjowane
0
zgodnie ze standardem.434 → 413
Usunięto instrukcję case: Jeśli do bezbarwnego skrzyżowania jest osiągalne zarówno z czerni, jak i bieli, możemy je policzyć jako jeden punkt dla obu, aby uprościć program. Przełączanie gałęzi logicznych, aby uniknąć negacji.
413 → 382
Przypisz,
d
abygetchar()+1
zapisać jedną parę nawiasów. Przy założeniu, żeb
jest on inicjowany na zera, zmień kolejnośćcase
instrukcji, odrzucając wszystkiebreak
instrukcje.(a>b?c:0)
jest dłuższy niż(a>b)*c
.(d+1)*g+e
jest dłuższy niżd*g+e+g
.382 → 364
Ulepszone zapętlanie, brak nowych linii na wyjściu, krótsze procedury wyjściowe.
364 → 336
Pozbyłem się tego
switch
oświadczenia. (Dzięki, Howard!), Śledź różnicę punktów dla dwóch postaci. Negujc
dla jednej postaci. cztery znaki w dużej lub klauzuli.336 → 323
Zastąpienie
&
przez%
umożliwia usunięcie nawiasów klamrowych dla czterech znaków. Połączyłem pierwiastek kwadratowy z pętlą wejściową dla około dziewięciu znaków (tak!), Usunąłemif
jeden znak.323 → 298
Wprowadzono makro,
H
aby zastąpić często występujący i nieporęcznyb[d*g+e]
konstrukt.298 → 294
Zmień
a&=~4
na,a&=3
ponieważ tylko każdy z nas obserwuje trzy najniższe bajtya
. Zmienił również do ciała pętli od((a=I])<3)?a|=...
celuI]<3?a=I]|...
, który jest dwa znaki krótszy. Wprowadźh
zamiast ponownego użyciac
, który jest krótszy o jedną postać.294 → 292
Wyeliminuj
h
zmienną. Jeśli testujemyc
z!c--
zamiast!c++
,c
równa się 0 na końcu pętli zalewania i dlatego może być użyty do tego celu, w którymh
był używany wcześniej (tj. Utrzymywanie wyniku).292 → 290
Zastąpić konstrukcję
d-46?f--:0
zd-46&&f--
, który jest krótszy od charakteru i połączyć dwa zadania doa
w pętli wewnętrznej.źródło
{b[f]=d-80?d-89?d-46?f--:0:5:6;f++;}
zapisania kilku znaków.J (
140136131129119117116 znaków)Po zwiększeniu moich umiejętności J, mogę w końcu złożyć podanie w J. To jednak trochę za długo.
Algorytm zaimplementowany w tym zgłoszeniu jest bardzo podobny do implementacji referencyjnej, ale różni się sposobem obsługi zajętych pól.
Oto rozwiązanie podzielone na więcej części dla łatwiejszego zrozumienia. Gra w golfa różni się nieco od tego, ale różnica nie jest bardzo duża.
źródło
GolfScript, 190 znaków
Skrypt stał się znacznie dłuższy niż myślałem na początku. Przekaż dowolne wejście na STDIN, a wyjście zostanie wydrukowane po zakończeniu programu.
źródło
Rubin (314)
może być krótszy z pewnym czasem:
źródło