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 byte
6 byte salvati grazie a Riley
6 byte salvati grazie ad Adnan
Dato che questa domanda ha più di un anno e non ha ancora risposte, ho pensato di provarlo.
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)
Provalo online!
Il programma legge la tabella in un file chiamato Ie stampa la tabella con le sue sedie std::out. Non ero sicuro di un sacco di casi limite, quindi ho preso il mio miglior giudizio (qualunque sia stato il minimo sforzo), ma sembra passare tutti i casi di test. Alcuni degli output non corrispondono esattamente ma hanno tutti lo stesso numero di sedie.
Spiegazione
La prima riga piuttosto semplicemente imposta alcune definizioni che ci salveranno byte in futuro:
(Disimballerò queste macro per la leggibilità nelle righe future)
n,i,o="\nI ";R=lambda x:range(1,x-1)
Quindi apriremo un file chiamato Iperché abbiamo già una variabile abbreviata, in modo da risparmiare qualche byte.
b=open("I").read().split("\n")
Abbiamo diviso lungo le nuove linee per creare un elenco di stringhe (le righe dell'immagine)
s=b.split(n)
Trovo quindi la lunghezza della linea più lunga in modo da poter riempire tutte le linee di quella lunghezza. (Aggiungo anche 3 perché abbiamo bisogno di un po 'di imbottitura aggiuntiva)
z=max(map(len,s))+3
Quindi eseguiamo l'imbottitura effettiva e creiamo un bordo di Icaratteri attorno al bordo. Questo perché avremo bisogno di dire in seguito la differenza tra l'interno e l'esterno della forma. Modificheremo anche il tipo di dati da un elenco di stringhe a un elenco di elenchi di caratteri (lunghezza 1 stringhe).
a=[list("I"+x.ljust(z,"I"))for x in["I"]+s+["I"]]
La riga successiva è solo un'altra definizione di salvataggio byte.
(Disimballerò anche questo)
B=R(len(a))
Ora vogliamo diffondere i Ipersonaggi ovunque al di fuori della forma. Possiamo farlo con un automa pseudo-cellulare. Ognuno Isi diffonderà a tutti i personaggi adiacenti . Potremmo eseguire il loop fino a quando l'automa non si stabilizza, tuttavia ciò non può richiedere più iterazioni di quanti siano i caratteri, quindi eseguiamo semplicemente il loop di tutti i caratteri in b(input originale)
for _ in b:
Per ogni iterazione vogliamo passare ogni carattere nell'elenco 2D (escluso il riempimento più esterno)
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):
Per ogni posizione eseguiamo il seguente codice:
if("I" in[a[x+1][y],a[x-1][y]]+a[x][y-1:y+2])&(a[x][y]==" "):a[x][y]=" "
Dividiamolo.
Abbiamo un if con due condizioni separate da un &(bit a bit and)
Il primo controlla semplicemente se c'è una Iin una delle celle adiacenti e il secondo controlla solo se la cella corrente è a " ". Se superiamo tali condizioni, impostiamo la cella corrente come I.
Ora che abbiamo determinato l'esterno e l'interno della forma, possiamo iniziare a posizionare le sedie attorno al tavolo.
Ancora una volta passiamo in rassegna tutte le celle (e impostiamo altre scorciatoie)
for x in range(1,len(a)-1):
A=a[x]
for y in range(1,z-1):
k=a[x+1][y]
Ora ecco la mia parte preferita. Se finora hai camminato a fatica nel mio golf noioso, principalmente basato sulla definizione, ti ricompenserò con una bella boccata di golf intelligente (se lo dico io stesso).
Un piccolo sfondo in pitone:
In Python se si tenta di assegnare una chiave del dizionario due volte, questa viene assegnata a quest'ultima. Per esempio
>>> {1:"a",1:"b"}[1]
'b'
Abuseremo di questa proprietà per assegnare la cella corrente a un determinato personaggio.
La prima condizione è
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"]
Se la cella si trova nel mezzo di un bordo di 3 _caratteri, riassegneremo la cella corrente e la cella sottostante. Lo assegneremo al risultato dell'indicizzazione di un dizionario sovraccarico di I. Innanzitutto impostiamo il nostro valore predefinito con la coppia, "I":"_"+a[x+1][y]ciò significa che se non ci sono cambiamenti, assegneremo le due celle ai loro valori originali. Quindi aggiungiamo la coppia a[x-1][y]:"^ ". Questo non farà nulla (importante) a meno che la cella sopra quella corrente ( a[x-1][y]) sia riempita con un I. Se ne ha uno I, sovrascriverà il valore predefinito dicendoci di posizionare una sedia nella cella corrente. Successivamente passiamo alla cella sotto la cella corrente se quella cella viene Inuovamente ignorata per posizionare una sedia rivolta verso l'alto sotto il punto corrente.
La condizione successiva è un po 'più semplice
if"|"==a[x][y]==a[x-1][y]:a[x][y]={"I":"|",A[y+1]:">",A[y-1]:"<"}["I"]
Controlliamo se la cella corrente e la cella sopra di essa sono entrambe |. In tal caso, creiamo un dizionario.
La prima coppia nel dizionario "I":"|"imposta l'impostazione predefinita. Poiché accediamo alla chiave Ise Inon viene riassegnata, tornerà automaticamente a |(il carattere che è già) e non farà nulla.
Aggiungiamo le due chiavi A[y+1]:">",A[y-1]:"<"Se una delle due celle a sinistra e a destra lo sono I, riassegnerà la cella corrente a una sedia che punta nella direzione dell'esterno.
Ora non ci resta che produrre. Tuttavia, non possiamo semplicemente stampare, ci sono un paio di cose di pulizia che dobbiamo fare prima. Dobbiamo riconvertire in una stringa e rimuovere tutte le Is che abbiamo creato. Questo è fatto in una riga.
print "\n".join(`y`[2::5]for y in a).replace("I"," ")