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 443 bayt
Riley sayesinde 6 bayt kurtarıldı
Adnan sayesinde 6 bayt kurtarıldı
Bu soru bir yaşın üzerinde olduğundan ve hala cevap alamadığı için bir deneyeyim dedim.
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)
Çevrimiçi deneyin!
Program masaya adında bir dosyayı okur ve masa I
sandalye ile birlikte yazdırır std::out
. Çok sayıda davadan emin değildim, bu yüzden en iyi kararımı verdim (en az çabayı gösterene). Çıktıların bazıları tam olarak uyuşmuyor ancak hepsinde aynı sayıda sandalye var.
açıklama
İlk satır oldukça ileride bizi bayttan kurtaracak bazı tanımlamalar yapar:
(Bu makroları gelecek satırlarda okunabilirlik açısından açacağım)
n,i,o="\nI ";R=lambda x:range(1,x-1)
Ardından adında bir dosya açacağız, I
çünkü bunun için kısa bir değişkenimiz var, bu yüzden birkaç bayt kazandırıyor.
b=open("I").read().split("\n")
Dizelerin bir listesini oluşturmak için newlines'a böleriz (Resmin satırları)
s=b.split(n)
Daha sonra en uzun çizginin uzunluğunu bulurum, böylece tüm çizgileri o uzunluğa yayabilirim. (Ayrıca biraz ekliyorum çünkü biraz daha fazla dolguya ihtiyacımız var)
z=max(map(len,s))+3
Sonra asıl dolguyu uygularız ve I
kenarlarında bir karakter sınırı oluştururuz . Bunun nedeni, şeklin daha sonra iç ve dış arasındaki farkı anlatmamız gerekecek. Ayrıca, veri tipini karakter listesinden bir karakter listesine (uzunluk 1 karakter dizisi) değiştireceğiz.
a=[list("I"+x.ljust(z,"I"))for x in["I"]+s+["I"]]
Bir sonraki satır sadece başka bir bayt tasarruf tanımıdır.
(Bunu da açacağım)
B=R(len(a))
Şimdi I
karakterleri şeklin dışındaki her yere yaymak istiyoruz . Bunu yalancı hücresel otomatlarla yapabiliriz. Her biri I
bitişik
karakterlere yayılır . Otomat stabilize olana kadar döngü yapabiliriz ancak bu karakterlerden daha fazla yineleme yapamaz, bu yüzden sadece karakterin içindeki her karakterin içine gireriz b
(orijinal girdi)
for _ in b:
Her yineleme için 2B listesindeki her karakterin üzerinden geçmek istiyoruz (en dıştaki dolgu hariç)
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):
Her pozisyon için aşağıdaki kodu çalıştırıyoruz:
if("I" in[a[x+1][y],a[x-1][y]]+a[x][y-1:y+2])&(a[x][y]==" "):a[x][y]=" "
Bunu yıkalım.
İki koşulu &
(bitsüz and
) ayıran bir if var
İlki I
, bitişik hücrelerin herhangi birinde bir var olup olmadığını, ikincisi ise mevcut hücrenin a olup olmadığını kontrol eder " "
. Bu şartları geçersek, mevcut hücreyi an olarak ayarladık I
.
Artık şeklin dışını ve içini belirlediğimize göre sandalyeleri masanın etrafına yerleştirmeye başlayabiliriz.
Bir kez daha tüm hücrelerin içinde dolaşıyoruz (ve biraz daha kısa saplar ayarlıyoruz)
for x in range(1,len(a)-1):
A=a[x]
for y in range(1,z-1):
k=a[x+1][y]
İşte en sevdiğim kısım. Eğer sıkıcı, çoğunlukla tanım tabanlı, şu ana kadar golf oynamaktan sıkıldım, sizi akıllı bir golf haberi ile ödüllendireceğim (eğer öyle söylersem).
Python'da küçük bir fon:
Python'da iki kez bir sözlük anahtarı atamaya çalışırsanız, sonuncusunu atar. Örneğin
>>> {1:"a",1:"b"}[1]
'b'
Geçerli hücreyi belirli bir karaktere atamak için bu özelliği kötüye kullanacağız.
İlk şart
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"]
Hücre, 3 _
karakterlik bir kenarın ortasındaysa , geçerli hücreyi ve altındaki hücreyi yeniden atarız. Aşırı yüklenmiş bir sözlüğün endekslemesinin sonucuna atayacağız I
. Öncelikle çiftimizi varsayılan olarak belirledik, "I":"_"+a[x+1][y]
bunun anlamı eğer değişiklik olmazsa iki hücreyi orijinal değerlerine geri atayacağız. Sonra çifti ekleyeceğiz a[x-1][y]:"^ "
. Geçerli olanın ( a[x-1][y]
) üzerindeki hücre bir ile doldurulmadıkça, bu hiçbir şeyi yapmaz (önemli) I
. İçinde varsa I
, geçerli hücreye sandalye yerleştirmemizi söyleyen varsayılanı geçersiz kılar. Daha sonra, eğer o hücre I
mevcut noktanın altına yukarı bakan bir sandalye yerleştirmek için tekrar geçersiz kılınırsa , mevcut hücrenin altındaki hücreye ilerleriz.
Bir sonraki durum biraz daha basit
if"|"==a[x][y]==a[x-1][y]:a[x][y]={"I":"|",A[y+1]:">",A[y-1]:"<"}["I"]
Mevcut hücrenin ve üzerindeki hücrenin her ikisinin de olup olmadığını kontrol ederiz |
. Öyleyse bir sözlük hazırladık.
Sözlükteki ilk çift "I":"|"
varsayılanı ayarlar. Biz anahtar erişmek için gidiyoruz yana I
eğer I
o geri varsayılan olarak tayin olur olmaz |
(karakter o zaten) ve hiçbir şey.
İki anahtarı ekliyoruz A[y+1]:">",A[y-1]:"<"
İki hücreden biri sola ve sağa ise I
o zaman mevcut hücreyi dışa dönük bir sandalyeye atar.
Şimdi sadece çıktı vermeliyiz. Ancak sadece baskı alamıyoruz, ilk önce yapmamız gereken birkaç temizlik işi var. Tekrar bir dizgeye dönüşmeli ve I
yarattığımız tüm harfleri kaldırmalıyız . Bu tek satırda yapılır.
print "\n".join(`y`[2::5]for y in a).replace("I"," ")