Game Scoring a Go adalah tugas yang tidak terlalu mudah. Di masa lalu ada beberapa perdebatan tentang bagaimana merancang aturan untuk mencakup semua kasus sudut aneh yang mungkin terjadi. Untungnya, dalam tugas ini Anda tidak perlu melakukan hal-hal rumit seperti hidup dan mati atau deteksi seki. Dalam tugas ini, Anda harus menerapkan program yang mencetak permainan sesuai dengan aturan Tromp-Taylor tanpa Komi.
Prosedur penilaiannya cukup sederhana:
sebuah titik P, bukan berwarna C, dikatakan mencapai C, jika ada jalur titik-titik warna P yang berdekatan (secara vertikal atau horizontal) dari P ke titik warna C.
Skor pemain adalah jumlah titik warnanya , ditambah jumlah titik kosong yang hanya mencapai warnanya.
Sebagai contoh, perhatikan papan berikut. X
, O
dan -
menunjukkan persimpangan hitam, putih dan tidak berwarna:
- - - 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 - - -
Menerapkan aturan penilaian menghasilkan hasil berikut. x
, o
dan -
mewakili persimpangan tidak berwarna yang dihitung sebagai titik hitam, putih, dan tidak ada orang.
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 - - -
Menurut diagram, hitam memiliki 23 poin, putih memiliki 29 titik wilayah. Dengan demikian, program Anda harus mencetak W+6
untuk board ini.
Saya harap ini cukup jelas seperti ini.
Masukan dan keluaran
Input adalah sebuah string yang berisi persis n ² karakter X
, O
, -
di mana n tidak diketahui pada waktu kompilasi. Program Anda harus mengabaikan semua karakter lain di aliran input. Perilaku tidak terdefinisi jika tidak ada bilangan bulat n sehingga jumlah XO-
karakter sama dengan n² . Anda dapat menganggap bahwa n ada di [0, 255] .
Urutan karakter harus ditafsirkan sebagai papan tulis dari n baris dan kolom. Output adalah nilai absolut dari perbedaan jumlah total titik putih dan hitam dalam representasi desimal. Jika putih memiliki lebih banyak poin, itu diawali oleh W+
, jika hitam memiliki lebih banyak poin itu diawali oleh B+
. Jika kedua pemain memiliki jumlah poin yang sama, hasilnya adalah Jigo
.
Input harus dibaca dengan cara yang ditentukan implementasi. Masukan mungkin bukan bagian dari kode sumber.
Kondisi menang
Ini adalah kode-golf. Konvensi kode-golf biasa berlaku. Pengajuan dengan jumlah karakter paling sedikit di sumbernya akan menang. Hanya program yang menerapkan spesifikasi sepenuhnya yang dapat menang.
Uji kasus
Memasukkan:
- - - 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 - - -
Keluaran: W+6
Memasukkan:
Xavier is insane -- says Oliver
Keluaran: Jigo
Inpout:
Code-Golf
Keluaran: Jigo
Memasukkan:
-XXXXXXX-XOOOOOOOXXO-OXXXOXXXOX--XOXXOOX
-
XOOXXOX--XOXXXOXXXO-OXXOOOOOOOX-XXXXXXX-
Keluaran: B+21
Memasukkan:
- - 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 - -
Keluaran: B+6
Lebih banyak testcases akan segera hadir.
implementasi referensi
Saya telah membuat implementasi referensi yang ditulis dalam ANSI C. Implementasi ini membaca input dari input standar dan menulis output ke output standar.
/* 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");
}
sumber
W+7
?S+
salah cetak (karena Anda sebelumnya terdaftar mungkin output sebagai baikW+
,B+
atauJigo
) dan saya melihat keyboard dan melihatS
dekatW
... Atau yang Anda gunakan Dvorak?Jawaban:
GolfScript (105 byte)
Demo online .
Isi banjir diadaptasi dari jawaban saya sebelumnya .
Solusinya mengisi-satu salinan papan asli dengan X, dan yang lain dengan O. Dengan demikian sel-sel kosong yang dapat dijangkau oleh kedua warna diberi skor untuk keduanya, tetapi batalkan dalam pengurangan.
sumber
C (
438434413382364336322298294292290 karakter)Semua baris baru kecuali yang pertama dimasukkan untuk meningkatkan keterbacaan. Versi komentar dan sedikit lebih terbaca dapat ditemukan di sini .
Jawaban ini pada dasarnya adalah solusi referensi tetapi dengan semua hal yang tidak berguna (seperti tipe [siapa yang butuh sesuatu yang berbeda
int
?] Dan kepatuhan standar [nilai pengembalian main? Tolong!])Koreksi dan perbaikan
438 → 434
Turunkan inisialisasi eksplisit variabel setelah saya meyakinkan diri sendiri bahwa mereka secara otomatis diinisialisasi
0
sesuai dengan standar.434 → 413
Pernyataan kasus yang dihapus: Jika persimpangan tidak berwarna dapat dicapai dari hitam dan putih, kita dapat menghitungnya sebagai satu titik untuk keduanya untuk menyederhanakan program. Beralih dari cabang logis untuk menghindari negasi.
413 → 382
Tetapkan
d
untukgetchar()+1
menyimpan sepasang kurung. Di bawah asumsi yangb
diinisialisasi ke nol, menyusun ulangcase
pernyataan, membuang semuabreak
pernyataan.(a>b?c:0)
lebih panjang dari(a>b)*c
.(d+1)*g+e
lebih panjang darid*g+e+g
.382 → 364
Peningkatan perulangan, tidak ada baris baru dalam output, rutinitas keluaran lebih pendek.
364 → 336
Singkirkan
switch
pernyataan itu. (Terima kasih, Howard!), Lacak perbedaan poin untuk dua karakter. Meniadakanc
untuk satu karakter. empat karakter dalam huruf besar atau klausa.336 → 323
Mengganti
&
dengan%
memungkinkan penghapusan kawat gigi untuk empat karakter. Menyatu akar kuadrat dengan loop input untuk sembilan atau lebih karakter (yeah!), Dihapusif
untuk satu karakter.323 → 298
Memperkenalkan makro
H
untuk menggantikanb[d*g+e]
konstruksi yang sering terjadi dan besar .298 → 294
Ubah
a&=~4
menjadia&=3
karena kami hanya mengamati tiga byte terendah daria
. Juga mengubah tubuh lingkaran dari((a=I])<3)?a|=...
keI]<3?a=I]|...
yang dua karakter lebih pendek. Juga, perkenalkanh
alih-alih menggunakan kembalic
, yang merupakan satu karakter lebih pendek.294 → 292
Hilangkan
h
variabel. Jika kita mengujic
dengan!c--
bukannya!c++
,c
sama dengan 0 pada akhir loop pengisian banjir dan dengan demikian dapat digunakan untuk tujuanh
yang digunakan sebelumnya (yaitu menjaga skor).292 → 290
Ganti konstruksi
d-46?f--:0
dengand-46&&f--
yang lebih pendek oleh karakter dan gabungkan dua tugas kea
dalam lingkaran dalam.sumber
{b[f]=d-80?d-89?d-46?f--:0:5:6;f++;}
menyimpan beberapa karakter.J (
140136131129119117116 karakter)Setelah meningkatkan keterampilan J saya, saya akhirnya bisa memberikan pengajuan dalam J. Ini agak lama.
Algoritma yang diterapkan oleh pengiriman ini sangat mirip dengan implementasi referensi tetapi berbeda dalam cara bidang yang ditangani ditangani.
Inilah solusinya yang dibagi menjadi beberapa bagian agar lebih mudah dipahami. Solusi golf sedikit berbeda dari itu, tetapi perbedaannya tidak terlalu besar.
sumber
GolfScript, 190 karakter
Script menjadi lebih lama dari yang saya pikirkan di awal. Lewati setiap input pada STDIN dan hasilnya kemudian akan dicetak ketika program berakhir.
sumber
Ruby (314)
dapat dibuat lebih pendek dengan lebih banyak waktu:
sumber