Bei gegebenem Tisch auf die Stühle setzen

41

Herausforderung

Sie erhalten eine Tabelle als Eingabe, gezeichnet mit ASCII |und _. Ihre Aufgabe ist es, die Stühle darum zu stellen.

Beispiel

Eingang:

 ____
|    |
|    |
|    |
|    |
|____|

Ausgabe:

 _^_^_
<     >
|     |
<     >
|     |
<_ _ _>
  v v

Diese Stühle bestehen aus <>und v^.

Ein anderes Beispiel:

Die Linie muss so viele Stühle wie möglich enthalten.

  _____
 |     |_____
 |           |
 |           |
 |           |
 |      _____|
 |_____|


  _^_^_
 <     |_^_^_
 |           >
 <           |
 |           |
 <      _ _ _>
 |_ _ _| v v
   v v

Zwischen jedem Stuhl muss ein Leerzeichen sein. Und >_^_^_<ist ungültig, sollte es sein |_^_^_|.

  _____       _____
 |     |_____|     |
 |                 |
 |                 |
 |                 |
 |      ___________|
 |_____|


  _^_^_       _^_^_
 <     |_^_^_|     >
 |                 |
 <                 >
 |                 |
 <      _ _ _ _ _ _>
 |_ _ _| v v v v v
   v v

Auf der Innenseite eines "Donuts" dürfen sich keine Stühle befinden.

  _________________
 |      _____      |
 |     |     |     |
 |     |     |     |
 |     |_____|     |
 |_________________|


  _^_^_^_^_^_^_^_^_
 <      _____      >
 |     |     |     |
 <     |     |     >
 |     |_____|     |
 <_ _ _ _ _ _ _ _ _>
   v v v v v v v v

^und vpriorisieren <und >. Kein Stuhl für sich allein (er muss mindestens einen haben |oder _in der Reihe stehen).

  _________________
 |      _____      |
 |     |     |     |
 |     |     |_____|
 |     |_____
 |___________|


  _^_^_^_^_^_^_^_^_
 <      _ _ _      >
 |     | v v |     |
 <     >     <_ _ _>
 |     |_^_^_  v v
 <_ _ _ _ _ _|
   v v v v v

Dies ist Codegolf, also gewinnt der kürzeste Code.

Tim
quelle
2
Ich bin verwirrt, warum sind die Stühle von den Seiten in den Tisch eingebettet?
Optimierer
Wenn ich mich richtig erinnere, hatte Ihr ursprünglicher Sandkastenpfosten einen Abstand zwischen der vertikalen Tischlinie und der Stuhllinie. Genauso wie zwischen den horizontalen Tischlinien und den Stühlen etwas Platz ist.
Optimierer
1
es sieht so aus, als ob die Stühle mit einem Abstand zueinander platziert sind, aber die Umgebung eines Eingangs ist nicht durch zwei teilbar. wie das Programm beginnen soll, Stühle zu setzen. im Uhrzeigersinn oder gegen den Uhrzeigersinn? von der oberen rechten Ecke, der oberen linken Ecke usw.?
1
Ich denke auch, dass es ein Problem im dritten Beispiel gibt - es gibt einen zusätzlichen Abstand zwischen dem zweiten und dritten "oberen" Stuhl - und auch im letzten Beispiel in der unteren rechten Ecke
1
Der erste Testfall scheint gebrochen zu sein. Die Eingabe ist nur 4 breit und die Ausgabe ist 5.
Weizen-Assistent

Antworten:

34

Python 2, 1033 1007 924 879 829 787 713 699 692 691 688 687 672 670 664 659 654 648 643 642 630 625 623 620 570 560 554 545 518 514 513 510 505 492 476 454 451 443 Bytes

6 Bytes gespart dank Riley

6 Bytes gespart dank Adnan

Da diese Frage über ein Jahr alt ist und noch keine Antworten hat, dachte ich, ich würde es versuchen.

n,i,o,u="\nI _";R=lambda x:range(1,x-1)
b=open(i).read()
s=b.split(n)
z=max(map(len,s))+3
a=[list(i+x.ljust(z,i))for x in[i]+s+[i]]
for x in R(len(a))*len(b):
 A=a[x];B=a[x+1];C=a[x-1]
 for y in R(z):
    D=A[y-1:y+2];k=B[y];j=A[y+1]
    if(i in[C[y],k]+D+(k==u)*B[y-1:y+2]or"V"==j)&(A[y]==o):A[y]=i
    if"|"==A[y]==C[y]:A[y]={i:"|",j:">",A[y-1]:"<"}[i]
    if[u]*3==D:A[y],B[y]={i:u+k,C[y]:"^"+k,k:" V"}[i]
print n.join(`y`[2::5]for y in a).replace(i,o)

Probieren Sie es online!

Das Programm liest aus der Tabelle eine Datei mit dem Namen Iund druckt die Tabelle mit ihren Stühlen aus std::out. Ich war mir bei einigen Randfällen nicht sicher, also habe ich mein bestes Urteil abgegeben (was auch immer die geringste Anstrengung erfordert hat), aber es scheint alle Testfälle zu bestehen. Einige der Ausgänge stimmen nicht genau überein, aber sie haben alle die gleiche Anzahl von Stühlen.

Erläuterung

Die erste Zeile legt einfach einige Definitionen fest, die uns in Zukunft Bytes sparen werden:

(Ich werde diese Makros für die Lesbarkeit in zukünftigen Zeilen entpacken)

n,i,o="\nI ";R=lambda x:range(1,x-1)

Dann werden wir eine Datei mit dem Namen öffnen, Iweil wir bereits eine Variable haben, die kurz dafür ist, so dass ein paar Bytes gespart werden.

b=open("I").read().split("\n")

Wir teilen uns entlang von Zeilenumbrüchen, um eine Liste von Zeichenfolgen zu erstellen (Die Zeilen des Bildes)

s=b.split(n)

Ich finde dann die Länge der längsten Zeile, so dass ich alle Zeilen auf diese Länge auffüllen kann. (Ich füge auch 3 hinzu, weil wir ein bisschen zusätzliche Polsterung brauchen)

 z=max(map(len,s))+3

Dann führen wir das eigentliche Auffüllen durch und erstellen einen Rand aus IZeichen am Rand. Dies liegt daran, dass wir später den Unterschied zwischen der Innenseite und der Außenseite der Form feststellen müssen. Wir werden auch den Datentyp von einer Liste von Zeichenketten in eine Liste von Zeichenketten (Länge 1 Zeichenketten) ändern.

a=[list("I"+x.ljust(z,"I"))for x in["I"]+s+["I"]]

Die nächste Zeile ist nur eine weitere Definition zum Speichern von Bytes.

(Ich werde auch dieses auspacken)

B=R(len(a))

Jetzt möchten wir die IZeichen auf alle Bereiche außerhalb der Form verteilen . Wir können dies mit einem Pseudozellularautomaten tun. Jedes Iwird sich auf alle benachbarten Zeichen ausbreiten . Wir konnten Schleife , bis der Automat jedoch stabilisiert dies kann nicht mehr Iterationen dauern , als es Zeichen , so dass wir nur eine Schleife durch alle Zeichen b(dem ursprünglichen Eingang)

for _ in b:

Bei jeder Iteration möchten wir jedes Zeichen in der 2D-Liste übergehen (mit Ausnahme der äußersten Auffüllung).

 for x in range(1,len(a)-1):
    A=a[x]  #<--Another definition I will fill in for clarity
    for y in range(1,z-1):

Für jede Position führen wir den folgenden Code aus:

if("I" in[a[x+1][y],a[x-1][y]]+a[x][y-1:y+2])&(a[x][y]==" "):a[x][y]=" "

Lassen Sie uns das aufschlüsseln.

Wir haben ein Wenn mit zwei Bedingungen, die durch ein &(bitweises and) getrennt sind.

Die erste prüft einfach, ob sich Iin einer der benachbarten Zellen eine befindet, und die zweite prüft einfach, ob die aktuelle Zelle eine ist " ". Wenn wir diese Bedingungen erfüllen, setzen wir die aktuelle Zelle auf eine I.


Nachdem wir das Äußere und Innere der Form bestimmt haben, können wir damit beginnen, die Stühle um den Tisch zu platzieren.

Nochmals durchlaufen wir alle Zellen (und setzen weitere Shorthands)

for x in range(1,len(a)-1):
 A=a[x]
 for y in range(1,z-1):
        k=a[x+1][y]

Hier ist mein Lieblingsteil. Wenn Sie sich bisher durch mein langweiliges, meist auf Definitionen basierendes Golfspiel geschlichen haben, werde ich Sie mit einem guten Schuss cleveren Golfspiels belohnen (wenn ich es selbst sage).

Ein kleiner Hintergrund in Python:

Wenn Sie in Python versuchen, einen Wörterbuchschlüssel zweimal zuzuweisen, weist er dem letzteren einen zu. Zum Beispiel

>>> {1:"a",1:"b"}[1]
'b'

Wir werden diese Eigenschaft missbrauchen, um die aktuelle Zelle einem bestimmten Zeichen zuzuweisen.

Die erste Bedingung ist

if["_"]*3==a[x][y-1:y+2]:a[x][y],a[x+1][y]={"I":"_"+a[x+1][y],a[x-1][y]:"^ ",a[x+1][y]:" V"}["I"]

Befindet sich die Zelle in der Mitte einer Kante mit 3 _Zeichen, werden die aktuelle Zelle und die Zelle darunter neu zugewiesen. Wir weisen es dem Ergebnis der Indizierung eines überladenen Wörterbuchs durch zu I. Wir setzen zuerst unseren Standardwert mit dem Paar, "I":"_"+a[x+1][y]dh wenn keine Änderung erfolgt, werden die beiden Zellen wieder auf ihre ursprünglichen Werte zurückgesetzt. Als nächstes fügen wir das Paar hinzu a[x-1][y]:"^ ". Dies macht nichts (wichtig), es sei denn, die Zelle über der aktuellen ( a[x-1][y]) ist mit einem gefüllt I. Wenn ein vorhanden Iist, wird der Standardwert überschrieben, der uns auffordert, einen Stuhl in der aktuellen Zelle zu platzieren. Als nächstes bewegen wir uns zu der Zelle unter der aktuellen Zelle, wenn diese Zelle Ierneut überschrieben wird, um einen nach oben gerichteten Stuhl unter der aktuellen Stelle zu platzieren.

Die nächste Bedingung ist ein bisschen einfacher

if"|"==a[x][y]==a[x-1][y]:a[x][y]={"I":"|",A[y+1]:">",A[y-1]:"<"}["I"]   

Wir prüfen, ob die aktuelle Zelle und die Zelle darüber beide sind |. In diesem Fall haben wir ein Wörterbuch erstellt.

Das erste Paar im Wörterbuch "I":"|"legt die Standardeinstellung fest. Da wir auf den Schlüssel zugreifen werden, Iwenn er Inicht neu zugewiesen wird, wird er standardmäßig auf |(das Zeichen, das er bereits ist) zurückgesetzt und es wird nichts unternommen.

Fügen Sie die beiden Tasten hinzu. A[y+1]:">",A[y-1]:"<"Wenn eine der beiden Zellen links und rechts ist I, wird die aktuelle Zelle einem Stuhl zugewiesen, der nach außen zeigt.


Jetzt müssen wir nur noch ausgeben. Wir können jedoch nicht einfach drucken, sondern müssen erst einige Dinge im Haushalt erledigen. Wir müssen zurück in einen String konvertieren und alle von Iuns erstellten s entfernen . Dies geschieht in einer Zeile.

print "\n".join(`y`[2::5]for y in a).replace("I"," ")
Weizen-Assistent
quelle
Können Sie nicht ein Leerzeichen für die erste Ebene des Einzugs, ein Tabulatorzeichen für zwei, ein Tabulatorzeichen und ein Leerzeichen für drei verwenden? Das spart ein paar Bytes.
Riley
3
Dies ist möglicherweise die am meisten umgolfende Antwort.
Magic Octopus Urn
2
Funktioniert i,o="I "anstatt zu i="I";o=" "arbeiten?
Adnan
1
@ErikGolfer nkostet 4 Bytes und spart mir 6. Obwohl ich es nicht oft benutze, spart es 2 Bytes.
Wheat Wizard
1
@ Pietu1998 Danke für den Hinweis. Ich habe das Problem behoben
Weizen-Zauberer