Segna una partita a Go


23

Segnare un gioco Go è un compito non troppo facile. In passato ci sono stati diversi dibattiti su come progettare regole per coprire tutti gli strani casi angolari che possono verificarsi. Fortunatamente, in questo compito non devi fare cose complicate come la vita o la morte o il rilevamento di seki. In questo compito, devi implementare un programma che segna un gioco secondo le regole di Tromp-Taylor senza Komi.
La procedura di punteggio è piuttosto semplice:

si dice che un punto P, non colorato C, raggiunga C, se esiste un percorso di punti adiacenti (verticalmente o orizzontalmente) del colore di P da P a un punto di colore C.
Il punteggio di un giocatore è il numero di punti del suo colore , oltre al numero di punti vuoti che raggiungono solo il suo colore.

Ad esempio, considera la seguente scheda. X, OE -denotano nero, bianco e incolori intersezioni:

- - - 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 - - -

L'applicazione della regola di punteggio produce il seguente risultato. x, oE -rappresentano le intersezioni non colorati che vengono conteggiati come nero, bianco e punti di nessuno.

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 - - -

Secondo il diagramma, il nero ha 23 punti, il bianco ha 29 punti di territorio. Pertanto, il tuo programma dovrebbe stampare W+6per questa scheda.

Spero sia abbastanza chiaro in questo modo.

Ingresso e uscita

L'ingresso è una stringa che contiene esattamente dei caratteri X, O, -dove n non è noto al momento della compilazione. Il programma dovrebbe ignorare tutti gli altri caratteri nel flusso di input. Il comportamento non è definito se non esiste un numero intero n tale che la quantità di XO-caratteri sia uguale a . Si può presumere che n sia in [0, 255] .

La sequenza di caratteri deve essere interpretata come un Go-board di n righe e colonne. L'output è il valore assoluto della differenza della quantità totale di punti di bianco e nero nella rappresentazione decimale. Se il bianco ha più punti, ha il prefisso W+, se il nero ha più punti è preceduto da B+. Nel caso in cui entrambi i giocatori abbiano lo stesso numero di punti, l'output è Jigo.

L'input deve essere letto in modo definito dall'implementazione. L'input potrebbe non far parte del codice sorgente.

Condizioni vincenti

Questo è code-golf. Si applicano le convenzioni convenzionali di code-golf. Vince l'invio con il minor numero di personaggi nella sua fonte. Solo i programmi che implementano pienamente le specifiche possono vincere.

Casi test

Ingresso:

- - - 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 - - -

Produzione: W+6

Ingresso:

Xavier is insane -- says Oliver

Produzione: Jigo

Inpout:

Code-Golf

Produzione: Jigo

Ingresso:

-XXXXXXX-XOOOOOOOXXO-OXXXOXXXOX--XOXXOOX
-
XOOXXOX--XOXXXOXXXO-OXXOOOOOOOX-XXXXXXX-

Produzione: B+21

Ingresso:

- - 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 - -

Produzione: B+6

Altri test verranno presto.

implementazione di riferimento

Ho creato un'implementazione di riferimento scritta in ANSI C. Questa implementazione legge l'input dall'input standard e scrive l'output nell'output standard.

/* 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");
}

Presumibilmente intendi l'ultimo output ad essere W+7?
dmckee,

No ... Come sei arrivato a questa conclusione?
FUZxxl,

Ehm ... ho pensato che S+fosse un errore di battitura (perché in precedenza elencato possibile uscita come sia W+, B+o Jigo) e ho guardato la mia tastiera e visto la Ssi trova nei pressi W... O si usa Dvorak?
dmckee,

@dmckee Suppongo che la "S" provenga dal tedesco "Schwarz" invece che "Nero".
Howard,

Oh ... hai ragione. Mi dispiace per questo
FUZxxl

Risposte:


2

GolfScript (105 byte)

{'-XO'?}/]-1-.{2*3%}%{.,:N),{.*N=}?/{{[{.2$+1={+.}*}*]}%zip}N*[]*.1--,\}2*-.{.0>'W+B+'2/=\abs}{;'Jigo'}if

Demo online .

Inondazione adattata da questa mia precedente risposta .

La soluzione riempie inondazioni una copia della scheda originale con X e un'altra con O. Pertanto le celle vuote che sono raggiungibili da entrambi i colori vengono segnate per entrambi, ma si annullano nella sottrazione.


Giusto. Potresti vincere questo round.
FUZxxl,

6

C ( 438 434 413 382 364 336 322 298 294 292 290 caratteri)

#define I b[d*g+e
a;b[65536];c;d;e;f;g;main(){for(;d=getchar()+1;f++)b[f]=d-80?d-89?d-46&&
f--:5:6,g+=g*g<f;while(!c--)for(d=g;d--;)for(e=g;e--;)I]<3?a=3&(I]|!!d*I
-g]|!!e*I-1]|(d<g-1)*I+g]|(e<g-1)*I+1]),c&=I]==a,I]=a:0;while(f--)c+=b[f
]%2-b[f]/2%2;printf(c?"%c+%i":"Jigo",c>0?66:87,abs(c));}

Tutte le nuove righe tranne la prima inserita per una migliore leggibilità. Una versione commentata e leggermente più leggibile è disponibile qui .

Questa risposta è essenzialmente la soluzione di riferimento ma con tutte quelle cose inutili (come i tipi [chi ha bisogno di qualcosa di diverso da intcomunque?] E la conformità agli standard [valore di ritorno di main? Per favore!])

Correzioni e miglioramenti

438 → 434

Inizializzazione esplicita abbandonata delle variabili dopo che mi sono convinto che sono inizializzati automaticamente 0secondo lo standard.

434 → 413

Dichiarazione del caso rimosso: se un incrocio non colorato è raggiungibile sia in bianco che in nero, possiamo considerarlo come un punto per entrambi per semplificare il programma. Cambio di rami logici per evitare la negazione.

413 → 382

Assegnare da getchar()+1per salvare una coppia di parentesi. Partendo dal presupposto che bè inizializzato a zero, riordinare le caseistruzioni, scartando tutte le breakistruzioni. (a>b?c:0)è più lungo di (a>b)*c. (d+1)*g+eè più lungo di d*g+e+g.

382 → 364

Looping migliorato, nessuna nuova riga nell'output, routine di output più brevi.

364 → 336

Mi sono sbarazzato di questa switchaffermazione. (Grazie, Howard!), Traccia la differenza di punti per due personaggi. Annulla cper un personaggio. quattro personaggi in grande o clausola.

336 → 323

La sostituzione &con %consente la rimozione di parentesi graffe per quattro caratteri. Fusa la radice quadrata con il ciclo di input per circa nove caratteri (sì!), Rimosso un carattere ifper un carattere.

323 → 298

Introdotta la macro Hper sostituire il b[d*g+e]costrutto spesso presente e voluminoso .

298 → 294

Passare a&=~4a a&=3come tutti osserviamo solo i tre byte più bassi di a. Anche cambiato al corpo loop dal ((a=I])<3)?a|=...al I]<3?a=I]|...quale è due caratteri più corta. Inoltre, introdurre hinvece di riutilizzare c, che è un personaggio più breve.

294 → 292

Elimina hvariabile. Se testiamo ccon !c--invece di !c++, è cuguale a 0 alla fine del ciclo di riempimento dell'inondazione e può quindi essere utilizzato per lo scopo hprecedentemente utilizzato (ovvero mantenimento del punteggio).

292 → 290

Sostituisci il costrutto d-46?f--:0con il d-46&&f--quale è più corto di un personaggio e combina i due compiti anel ciclo interno.


1
È possibile sostituire l'istruzione switch con qualcosa di simile {b[f]=d-80?d-89?d-46?f--:0:5:6;f++;}per salvare diversi caratteri.
Howard,

@Howard: Sì. Ha funzionato davvero bene! Grazie
FUZxxl,

"Per una migliore leggibilità" - come se.
tomsmeding,

@tomsmeding Bene, lo scorrimento di una riga è molto meno leggibile. Inoltre, è collegata una versione commentata.
FUZxxl,

@FUZxxl Ciò significava scherzosamente. :) Inoltre, hai ragione nel dire che è meglio che su 1 riga.
tomsmeding,

6

J ( 140 136 131 129 119 117 116 caratteri)

Dopo aver aumentato le mie abilità di J, posso finalmente fornire un contributo in J. È un po 'lungo però.

exit echo>(*{'Jigo';('B+',":);'W+',":@|)+/,-/1 2=/(]OR(0=[)*[:OR((,.|.)0,i:1)|.!.0])^:_~($~,~@%:@#)3-.~'-XO'i:1!:1]3

L'algoritmo implementato da questo invio è molto simile all'implementazione di riferimento ma diverso nel modo in cui vengono gestiti i campi occupati.

Ecco la soluzione suddivisa in più parti per una più facile comprensione. La soluzione golf è leggermente diversa da quella, ma la differenza non è molto grande.

input =. 3 -.~ '-XO' i: 1!:1 ] 3
board =. ($~ ,~@%:@#) input
NB. shift up, down, left, right
rotm =. (,. |.) 0 , i: 1
fill =. ] OR (0 = [) * [: OR rotm |.!.0 ]
filledboard =. fill^:_~ board
score =. +/ , -/ 1 2 =/ filledboard
echo > (* { 'Jigo' ; ('B+' , ":) ; ('W+', ":@|)) score
exit 0

5

GolfScript, 190 caratteri

{"XO-"?)},:v,.),\{\.*=}+,~:s.*:`0\,{s%!\2*+}/:r;88{0v@{=\2*+}+/}:%~79%1${{:<.r|r^2*|<2/r|r^|<2s?:h/|<h*|1$|1$^2`?(&}`*}:a~@@a\;.2$|2${^2*)2base{+}*}:m~@2$|@m-.{"BW"1/1$0>="+"@abs}{;"Jigo"}if

La sceneggiatura è diventata molto più lunga di quanto pensassi all'inizio. Passare qualsiasi input su STDIN e l'output verrà quindi stampato al termine del programma.


2

Rubino (314)

potrebbe essere ridotto con un po 'più di tempo:

q={?-=>0,?X=>5,?O=>6};b=[];$<.chars{|c|(t=q[c])&&b<<t}
z=Math.sqrt b.size
loop{c=b.each_with_index.map{|h,i|
next h if h>2
x=i%z
y=i/z
u=y<1?0:b[i-z]
l=x<1?0:b[i-1]
d=y>z-2?0:b[i+z]
r=x>z-2?0:b[i+1]
~4&(h|u|d|l|r)}
break if c==b
b=c}
b.map!{|h|h&~4}
s=b.count(1)-b.count(2)
puts s==0?"Jigo":s>0?"B+#{s}":"W+#{-s}"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.