Machen Sie einen Zug auf einem Go-Brett

13

Sie erhalten eine Brettposition für ein Go-Spiel und einen Zug zum Spielen. Sie müssen ausgeben, ob der Umzug legal ist oder nicht, und die neue Vorstandsposition, wenn es legal ist.

Eine kurze Erklärung der Go-Moves: Das Spiel besteht darin, abwechselnd schwarze und weiße Steine ​​("Steine") an leeren Stellen auf einem quadratischen Brett zu platzieren. Sätze von Teilen der gleichen Farbe, die miteinander verbunden sind (4-Wege), werden als Gruppen bezeichnet. Leere Stellen auf dem Spielplan, die an eine Gruppe angrenzen (auch 4-Wege), gelten als "Freiheiten" dieser Gruppe. Eine Gruppe mit 0 Freiheiten wird erfasst (vom Board entfernt). Ein Zug, der dazu führen würde, dass eine eigene Gruppe gefangen genommen wird ("Selbstmord"), ist illegal, es sei denn, er nimmt eine oder mehrere gegnerische Gruppen gefangen (und erhält dabei Freiheiten, so dass er nicht tatsächlich gefangen genommen wird).

Für die Betroffenen müssen Sie sich nicht mit Ko (und Superko) befassen, dh Sie können davon ausgehen, dass eine Ko-Erfassung legal ist. Wenn Sie nicht wissen, was das bedeutet, befolgen Sie einfach die obigen Regeln und es wird in Ordnung sein.

Eingabe: Eine Zahl n zwischen 2 und 19 (einschließlich), die die Kartengröße darstellt, gefolgt von n Zeilen mit n Zahlen zwischen 0 und 2 (einschließlich), die die Kartenposition darstellen, gefolgt von 3 durch Leerzeichen getrennten Zahlen, die den auszuführenden Zug darstellen. In der Brettposition bedeutet 0 eine leere Stelle, 1 einen schwarzen Stein und 2 einen weißen Stein. Der Zug gibt die Spalte, die Reihe und die Farbe (1 oder 2) des zu platzierenden Steins an. Die Spalten und Zeilen basieren auf 0 und reichen von 0 bis n-1 (einschließlich). Sie werden in derselben Reihenfolge wie die Platineneingabe gezählt.

Sie können davon ausgehen, dass die angegebene Vorstandsposition legal ist (alle Gruppen haben mindestens eine Freiheit).

Ausgabe: Eine Zeile mit 1 oder 0 (oder true / false, wenn Sie dies vorziehen), wenn der Zug legal ist oder nicht, gefolgt von der neuen Boardposition im selben Format wie die Eingabe.

Bewertung: Anzahl der Bytes des gesamten Quellcodes, kleiner ist besser. 20% zusätzliche Strafe für die Verwendung von Nicht-ASCII-Zeichen und 20% zusätzliche Strafe, wenn Ihr Code unter Linux nicht mit frei verfügbarer Software getestet werden kann.

Regeln: Keine Netzwerkverbindungen und keine Bibliotheken von Drittanbietern. Ihr Programm sollte die Standardeingabe- und -ausgabestreams oder das Standardäquivalent für Ihre Programmiersprache verwenden.

Beispiele:

1) Input:

2
10
01
1 0 2

Output:

0

2) Input:

2
10
11
1 0 2

Output:

1
02
00

3) Input:

5
22122
22021
11211
02120
00120
2 1 1

Output:

1
00100
00101
11011
02120
00120

4) Input:

6
000000
011221
121121
122221
011110
000000
4 0 1

Output:

1
000010
011221
121121
122221
011110
000000
aditsu
quelle

Antworten:

2

Python 3 (557 504 488)

import sys
s=sys.stdin
M=int(next(s))+1
j=Z=M*M-M
S=s.read(Z)
P=0
b=[0]*3
while j>0:j-=1+(j%M<1);b[int(S[j])]|=1<<j;P|=1<<j
N=lambda x:(x<<1|x>>1|x<<M|x>>M)&P&~x
def h(a,b):t=a|N(a)&b;return h(t,b)if t!=a else a
c,r,m=map(int,next(s).split())
o=m%2+1
p=1<<M*r+c
b[m]|=p
for n in(p<<1,p>>1,p<<M,p>>M):
 e=h(n&P,b[o])
 if~b[m]&N(e)<1<=n&b[o]:b[o]&=~e
_,B,W=b
g=~b[o]&N(h(p,b[m]))>=1>~_&p
print(+g)
q=''
while j<Z:
 r=1<<j
 if g*j%M>M-2:print(q);q=''
 else:q+='012E'[(r&B>0)+(r&W>0)*2]
 j+=1

Verwendet 3 Bitfelder zur Darstellung der Karte - jeweils eines für schwarze, weiße und leere Felder. Macht das Finden von Nachbarn Nund Kettenoperationen hsehr übersichtlich.

Eine ungolfed Version mit vielen Kommentaren: https://gist.github.com/airfrog/8429006

Luftfrosch
quelle
Sie haben eine Menge Leerzeichen am Ende jeder Zeile, die Datei, wie Sie es gepostet haben, hat 2732 Bytes.
Aditsu
@aditsu Das sollte jetzt behoben sein
airfrog
Größe ist immer noch falsch, sollte jetzt 555 sein :) Auch ich frage mich, ob Sie noch ein paar Bytes sparen können, indem Sie mehr Semikolons verwenden.
Aditsu
Fehler? Eingabe: 6 000000 011221 121121 122221 011110 000000 4 0 1Ausgabe: 0. Jetzt als Beispiel
hinzugefügt
Dieser Fehler ist behoben, ich habe auch einen weiteren Fehler beim Golfen gefunden und behoben, den Sie vielleicht als Beispiel hinzufügen möchten. Eingabe: Die 5 22100 20211 12211 12120 01120 1 1 2Ausgabe sollte 0 sein.
airfrog
2

Python ( 912 1004)

def o():
 n=int(raw_input(''))
 i=[raw_input('') for r in range(n+1)]
 b=[map(int,list(r)) for r in i[:n]]
 u,v,w=map(int,i[n].split(' '))
 if b[v][u]!=0:return 0
 b[v][u]=w
 if w==1:q=2
 elif w==2:q=1
 else:return 0
 f=[[],[],[]]
 h=[[],[],[]]
 g=[range(z*n,(z+1)*n) for z in range(n)]
 d=[(1,0),(-1,0),(0,1),(0,-1)]
 m=lambda z:max(0,min(n-1,z))
 t=[0,1,2,0,1]
 for j,s in enumerate(t):
  for r in range(n):
   for c in range(n):
    for y,x in map(lambda p:(m(r+p[0]),m(c+p[1])),d):
     if s==0:
      if b[y][x]==b[r][c]:
       if g[y][x]!=min(g[y][x],g[r][c]):
        t.insert(j+1,0)
       g[y][x]=g[r][c]=min(g[y][x],g[r][c])
     elif s==1:
      if g[r][c] not in h[b[r][c]]:
       h[b[r][c]].append(g[r][c])
      if b[y][x]==0 and g[r][c] not in f[b[r][c]]:
       f[b[r][c]].append(g[r][c])
    if s==2:
     if b[r][c]==q and g[r][c] not in f[b[r][c]]:
      b[r][c]=0
 h[w].sort()
 f[w].sort()
 if h[w]!=f[w]:return 0
 return "1\n"+'\n'.join([''.join(map(str,r)) for r in b])
print o()

Gehen Sie durch: Analysieren Sie die Eingabe, prüfen Sie, ob sich die Bewegung auf einer leeren Stelle befindet, führen Sie eine Bewegung durch, initiieren Sie das "Gruppen" -Gitter, vereinfachen / minimieren Sie das Gruppengitter, indem Sie die Farbe der angrenzenden Steine ​​(s = 0) überprüfen und wiederholen, bis sie vollständig minimiert ist für Gruppenfreiheiten (s = 1) entferne Gegnersteine ​​für Gruppen ohne Freiheiten (s = 2), wiederhole s = 0 und s = 1, überprüfe, ob alle Spielergruppen Freiheiten haben, gib das Ergebnis zurück.

Dies kann wahrscheinlich erheblich verkürzt werden ...

Interaktives Beispiel läuft:

2
10
01
1 0 2
0

2
10
11
1 0 2
1
02
00

5
22122
22021
11211
02120
00120
2 1 1
1
00100
00101
11011
02120
00120

6
000000
011221
121121
122221
011110
000000
4 0 1
1
000010
011221
121121
122221
011110
000000
jur
quelle
1
Ihr Programm macht nichts, es definiert nur eine Funktion.
Aditsu
Führen Sie es interaktiv aus und rufen Sie es mit print o () auf, wie im Beispiel run ...
jur
Nee. Es soll ein eigenständiges Programm sein, das Sie über die Befehlszeile ausführen. Außerdem würde das es auch kürzer machen.
Aditsu
Behebung durch Hinzufügen von print o () in der letzten Zeile
jur
Warum nicht einfach den Funktionskörper (outdented) verwenden? Und ich denke, Sie scheitern auch am neu hinzugefügten Beispiel 4.
aditsu