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 byte disimpan berkat Riley
6 byte disimpan berkat Adnan
Karena pertanyaan ini sudah berusia lebih dari satu tahun dan masih belum memiliki jawaban, saya pikir saya akan mencobanya.
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)
Cobalah online!
Program membaca tabel nama file I
dan mencetak tabel dengan kursinya std::out
. Saya tidak yakin tentang banyak kasus tepi jadi saya mengambil penilaian terbaik saya (apa pun yang paling sedikit usaha) tetapi tampaknya melewati semua kasus uji. Beberapa output tidak sama persis tetapi mereka semua memiliki jumlah kursi yang sama.
Penjelasan
Baris pertama cukup membuat beberapa definisi yang akan menyelamatkan kita byte di masa depan:
(Saya akan membongkar makro ini untuk dibaca di baris mendatang)
n,i,o="\nI ";R=lambda x:range(1,x-1)
Kemudian kita akan membuka file bernama I
karena kita sudah memiliki variabel yang merupakan kependekan dari itu sehingga menghemat beberapa byte.
b=open("I").read().split("\n")
Kami membagi sepanjang baris baru untuk membuat daftar string (Baris gambar)
s=b.split(n)
Saya kemudian menemukan panjang garis terpanjang sehingga saya bisa mengisi semua garis dengan panjang itu. (Saya juga menambahkan 3 karena kami membutuhkan sedikit tambahan tambahan)
z=max(map(len,s))+3
Kemudian kami melakukan padding yang sebenarnya dan membuat batas I
karakter di sekitar tepi. Ini karena kita perlu memberi tahu perbedaan antara bagian dalam dan bagian luar bentuk nanti. Kami juga akan mengubah tipe data dari daftar string ke daftar daftar karakter (panjang 1 string).
a=[list("I"+x.ljust(z,"I"))for x in["I"]+s+["I"]]
Baris berikutnya hanyalah definisi penghematan byte lain.
(Saya juga akan membongkar yang ini)
B=R(len(a))
Sekarang kami ingin menyebarkan I
karakter ke mana saja di luar bentuk. Kita dapat melakukan ini dengan otomat pseudo-seluler. Masing I
- masing akan menyebar ke
karakter yang berdekatan . Kita dapat mengulang sampai otomat stabil tetapi ini tidak dapat mengambil lebih banyak iterasi daripada karakter sehingga kita hanya mengulang setiap karakter dalam b
(input asli)
for _ in b:
Untuk setiap iterasi kami ingin melewati setiap karakter dalam daftar 2D (tidak termasuk padding terluar)
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):
Untuk setiap posisi kami menjalankan kode berikut:
if("I" in[a[x+1][y],a[x-1][y]]+a[x][y-1:y+2])&(a[x][y]==" "):a[x][y]=" "
Mari kita hancurkan ini.
Kami memiliki if dengan dua kondisi yang dipisahkan oleh &
(bitwise and
)
Yang pertama hanya memeriksa apakah ada I
di salah satu sel yang berdekatan dan yang kedua hanya memeriksa apakah sel saat ini adalah a " "
. Jika kami melewati kondisi tersebut, kami menetapkan sel saat ini menjadi I
.
Sekarang kita telah menentukan bagian luar dan dalam bentuknya, kita dapat mulai menempatkan kursi di sekeliling meja.
Sekali lagi kita mengulang semua sel (dan mengatur beberapa singkatan lagi)
for x in range(1,len(a)-1):
A=a[x]
for y in range(1,z-1):
k=a[x+1][y]
Sekarang inilah bagian favorit saya. Jika Anda berjalan dengan susah payah melalui golf yang membosankan, sebagian besar berbasis definisi, sejauh ini saya akan menghadiahi Anda dengan berita gembira yang bagus tentang bermain golf pintar (jika saya mengatakannya sendiri).
Sedikit latar belakang python:
Dalam Python jika Anda mencoba untuk menetapkan kunci kamus dua kali itu menandakan yang terakhir. Sebagai contoh
>>> {1:"a",1:"b"}[1]
'b'
Kami akan menyalahgunakan properti ini untuk menetapkan sel saat ini ke karakter tertentu.
Kondisi pertama adalah
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"]
Jika sel berada di tengah-tengah tepi 3 _
karakter, kami akan menugaskan kembali sel saat ini dan sel di bawahnya. Kami akan menetapkannya ke hasil pengindeksan kamus yang kelebihan beban oleh I
. Kami pertama-tama menetapkan default kami dengan pasangan "I":"_"+a[x+1][y]
ini artinya jika tidak ada perubahan kami akan menetapkan dua sel kembali ke nilai aslinya. Selanjutnya kita tambahkan pasangan a[x-1][y]:"^ "
. Ini tidak akan melakukan apa pun (penting) kecuali sel di atas yang sekarang ( a[x-1][y]
) diisi dengan I
. Jika ada I
di dalamnya, maka akan menimpa default yang memberitahu kita untuk menempatkan kursi di sel saat ini. Selanjutnya kita beralih ke sel di bawah sel saat ini jika sel itu I
kita timpa lagi untuk menempatkan kursi menghadap ke atas di bawah tempat saat ini.
Kondisi selanjutnya sedikit lebih sederhana
if"|"==a[x][y]==a[x-1][y]:a[x][y]={"I":"|",A[y+1]:">",A[y-1]:"<"}["I"]
Kami memeriksa apakah sel saat ini dan sel di atas keduanya |
. Jika demikian, kami membuat kamus.
Pasangan pertama dalam kamus "I":"|"
menetapkan standar. Karena kita akan mengakses kunci I
jika I
tidak dipindahkan maka akan kembali ke default |
(karakter sudah ada) dan tidak melakukan apa-apa.
Kita menambahkan dua kunci. A[y+1]:">",A[y-1]:"<"
Jika salah satu dari dua sel di kiri dan kanan, I
maka itu akan menugaskan kembali sel saat ini ke kursi yang menunjuk ke arah luar.
Sekarang kita hanya perlu output. Namun kita tidak bisa hanya mencetak, ada beberapa hal yang harus kita lakukan terlebih dahulu. Kami harus mengonversi kembali ke string dan menghapus semua yang I
kami buat. Ini dilakukan dalam satu baris.
print "\n".join(`y`[2::5]for y in a).replace("I"," ")