#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 bytes
6 bytes saved thanks to Riley
Since this question is over a year old and still has no answers I thought I'd give it a try. My answer is not particularly well golfed but it does the task.
l=n="\n";i="I";o=" ";R=lambda x:range(1,x-1)
s=open(i).read().split(n)
z=max(map(len,s))+3
a=[list(i+x.ljust(z,i))for x in[i]+s+[i]]
while a!=l:
for x in R(len(a)):
A=a[x];l=a
for y in R(z):
if(i in[a[x+1][y],a[x-1][y]]+A[y-1:y+2])&(A[y]==o):A[y]=i
for x in R(len(a)):
A=a[x];H=lambda z:(a[x+z][y],set(A[y-1:y+2]))==(i,{"_"})
for y in R(z):
if H(-1):A[y]="^"
if H(1):A[y],a[x+1][y]=o,"V"
if(A[y]=="|")&(a[x-1][y]in" |"):A[y]={i:"|",A[y+1]:">",A[y-1]:"<"}[i]
print n.join(`y`[2::5]for y in a).replace(i,o)
The program reads the table a file named I
and prints the table with its chairs to std::out
. I was not sure about a bunch of the edge cases so I took my best judgement (whatever took the least effort) but it seems to pass all the test cases. Some of the outputs don't match exactly but they all have the same number of chairs.
##Explanation
I will write a more thorough explanation but in the meantime here is an ungolfed version of my code:
import re
string = open("I"),read()
print string
size = len(max(string.split("\n"),key=len))
string = string.replace(" ","I")
string = "\n".join(map(lambda x:" "+x.ljust(size+1,"I")+" ",string.split('\n')))
size += 3
string = " "*(size)+"\n"+string+"\n"+" "*(size)
array = map(list,string.split("\n"))
last = ""
while string != last:
last = string
array = map(list,string.split("\n"))
for x in range(1,len(array)-1):
for y in range(1,size-1):
if array[x][y] == "I" and " " in [array[x+1][y], array[x-1][y], array[x][y+1], array[x][y-1]]:
array[x][y]=" "
string = "\n".join(map(lambda x:"".join(x),array))
print string
for x in range(1,len(array)-1):
for y in range(1,size-1):
if array[x][y]=="_" and array[x-1][y]==" " and all([b == "_" for b in [array[x][y-1],array[x][y+1]]]):
array[x][y] = "^"
if array[x][y]=="_" and array[x+1][y]==" " and all([b == "_" for b in [array[x][y-1],array[x][y+1]]]):
array[x][y] = "V"
if array[x][y]=="|" and array[x][y+1]==" " and array[x-1][y]in" |":
array[x][y] = ">"
if array[x][y]=="|" and array[x][y-1]==" " and array[x-1][y]in" |":
array[x][y] = "<"
for x in range(1,len(array)-1):
for y in range(1,size-1):
if array[x][y] == "_" and array[x+1][y]==" " and array[x][y-1]=="_" and array[x][y+1]=="|":
array[x][y]="V"
string = "\n".join(map(lambda x:"".join(x),array))
print string
for x in range(len(array)-1,1,-1):
for y in range(0,size):
if array[x][y] == "V":
array[x][y] = " "
array[x+1][y] = "V"
string = "\n".join(map(lambda x:"".join(x),array))
print string
string = string.replace("I"," ")
print string
If you have any suggestions feel free to comment them there is certainly room for improvement.