Забить игру в Го - задача не из легких. В прошлом было несколько споров о том, как разработать правила, чтобы охватить все странные случаи, которые могут возникнуть. К счастью, в этом задании вам не нужно делать сложные вещи, такие как жизнь и смерть или обнаружение секи. В этом задании вы должны реализовать программу, которая оценивает игру по правилам Тромпа-Тейлора без Коми.
Процедура подсчета очков довольно проста:
говорят, что точка P, не окрашенная в C, достигает C, если существует путь (по вертикали или горизонтали) смежных точек цвета P от P до точки цвета C.
Оценка игрока - это количество очков ее цвета. плюс количество пустых точек, которые достигают только ее цвета.
Например, рассмотрим следующую доску. X
, O
И -
обозначают черные, белые и неокрашенные перекрестки:
- - - 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 - - -
Применение правила оценки дает следующий результат. x
, 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
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 - - -
Согласно диаграмме, у черных 23 очка, у белых 29 точек территории. Таким образом, ваша программа должна печатать W+6
для этой доски.
Я надеюсь, что так понятно.
Вход и выход
Вход является строкой , которая содержит ровно n² из символов X
, O
, -
где п не известен во время компиляции. Ваша программа должна игнорировать все другие символы в потоке ввода. Поведение не определено, если нет такого целого числа n , что количество XO-
символов равно n² . Вы можете предположить, что n находится в [0, 255] .
Последовательность символов следует интерпретировать как доску из n строк и столбцов. На выходе получается абсолютное значение разницы общего количества точек белого и черного в десятичном представлении. Если белые имеют больше очков, он предваряется W+
, если черные имеют больше очков он приставка B+
. Если у обоих игроков одинаковое количество очков, результат будет Jigo
.
Ввод должен быть прочитан способом, определяемым реализацией. Ввод не может быть частью исходного кода.
Условия выигрыша
Это код-гольф. Применяются обычные правила игры в гольф. Представление с наименьшим количеством символов в источнике выигрывает. Только программы, которые полностью реализуют спецификацию, могут победить.
Контрольные примеры
Входные данные:
- - - 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 - - -
Выход: W+6
Входные данные:
Xavier is insane -- says Oliver
Выход: Jigo
Inpout:
Code-Golf
Выход: Jigo
Входные данные:
-XXXXXXX-XOOOOOOOXXO-OXXXOXXXOX--XOXXOOX
-
XOOXXOX--XOXXXOXXXO-OXXOOOOOOOX-XXXXXXX-
Выход: B+21
Входные данные:
- - 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 - -
Выход: B+6
Скоро появятся новые тесты.
эталонная реализация
Я создал эталонную реализацию, написанную на ANSI C. Эта реализация считывает ввод со стандартного ввода и записывает вывод в стандартный вывод.
/* 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");
}
источник
W+7
?S+
была опечатка (потому что ранее перечисленные возможные выходные или какW+
,B+
илиJigo
) , и я смотрел на мою клавиатуру и увиделS
рядомW
... Или вы используете Дворжака?Ответы:
GolfScript (105 байт)
Демо онлайн .
Flood-fill адаптирован из этого моего предыдущего ответа .
Решение заполняет одну копию исходной доски X, а другую - O. Таким образом, пустые ячейки, доступные обоим цветам, оцениваются для обоих, но отменяются при вычитании.
источник
C (
438434413382364336322298294292290 знаков)Все символы новой строки, кроме первой, вставлены для улучшения читаемости. Комментируемую и чуть более разборчивую версию можно найти здесь .
Этот ответ по сути является эталонным решением, но со всеми этими бесполезными вещами (такими как типы [кому что-то нужно от чего-либо отличного
int
?] И соответствие стандартам [возвращаемое значение main? Пожалуйста!])Исправления и улучшения
438 → 434
Отбросил явную инициализацию переменных после того, как убедился в том, что они автоматически инициализируются
0
согласно стандарту.434 → 413
Утверждение удаленного случая: если неокрашенное пересечение достижимо как из черного, так и из белого, мы можем посчитать его как одно очко для упрощения программы. Переключение логических веток, чтобы избежать отрицания.
413 → 382
Назначьте,
d
чтобыgetchar()+1
сохранить одну пару скобок. В предположении, чтоb
инициализируется в нули, изменить порядокcase
заявлений, отбрасывая всеbreak
утверждения.(a>b?c:0)
длиннее чем(a>b)*c
.(d+1)*g+e
длиннее чемd*g+e+g
.382 → 364
Улучшены циклы, нет новых строк в выводе, более короткие процедуры вывода.
364 → 336
Избавился от этого
switch
заявления. (Спасибо, Говард!), Отслеживайте разницу очков для двух персонажей. Отрицаниеc
за одного персонажа. четыре символа в большом или оговорке.336 → 323
Замена
&
на%
позволяет удалить фигурные скобки для четырех символов. Слил квадратный корень с входным циклом для девяти или около того символов (да!), Удалилif
для одного символа.323 → 298
Введен макрос
H
для замены часто встречающейся и громоздкойb[d*g+e]
конструкции.298 → 294
Измените
a&=~4
на,a&=3
поскольку мы наблюдаем только самые младшие три байтаa
. Также изменено тело цикла,((a=I])<3)?a|=...
наI]<3?a=I]|...
которое короче два символа. Кроме того, введитеh
вместо повторного использованияc
, что на один символ короче.294 → 292
Устранить
h
переменную. Если мы протестируемc
с!c--
вместо!c++
,c
равно 0 в конце цикла наводнения заполнения и , таким образом , может быть использована для этой целиh
была использована ранее (т.е. балла держать).292 → 290
Заменить конструкцию
d-46?f--:0
сd-46&&f--
которой короче по характеру и объединить эти два задания , чтобыa
во внутреннем цикле.источник
{b[f]=d-80?d-89?d-46?f--:0:5:6;f++;}
сохранения нескольких символов.J (
140136131129119117116 знаков)После наращивания своих навыков в области J, я, наконец, могу представить представление в J. Хотя это немного долго.
Алгоритм, реализованный в этом представлении, очень похож на эталонную реализацию, но отличается тем, как обрабатываются занятые поля.
Вот решение, разделенное на несколько частей, для облегчения понимания. Решение для игры в гольф немного отличается от этого, но разница не очень большая.
источник
GolfScript, 190 символов
Сценарий стал намного длиннее, чем я думал в начале. Передайте любой ввод в STDIN, и затем вывод будет напечатан после завершения программы.
источник
Рубин (314)
можно сделать короче с еще немного времени:
источник