Permütasyon Yolu Çizme


20

Aşağıdaki diyagramları dikey çapraz kesişen tüpler kümesi olarak düşünün.

1 2    1 2    1 2 3 4
\ /    \ /    \ / \ /
 X      |      |   |
/ \    / \    / \ / \
2 1    1 2   |   X   |
              \ / \ /
               X   X
              / \ / \
              3 1 4 2

En soldaki diyagramda, 1ve 2kendi eğik çizgilerini aşağı doğru kaydırın, çaprazlayın Xve başladıkları yerden karşı taraflardan çıkın.

Orta şemada aynı fikirdir, ancak |yolların kesişmediğini gösterir, bu nedenle hiçbir şey değişmez.

En sağdaki diyagramı gösterir daha karmaşık bir boru olduğu değiştiren permütasyon kodunun değiştirilmesini yönlendirme 1 2 3 4içine 3 1 4 2.

Hedef

Amacınız bu kod golf meydan okumak gibi bu "tüp yönlendirme diyagramları" gibi bir permütasyon verilen 3 1 4 2. Bayt cinsinden en kısa program kazanacaktır.

ayrıntılar

  1. Girdi stdin'den, 1'den n'ye kadar olan sayıların boşluklarla ayrılmış sayılarının permütasyonu olarak gelir , burada n pozitif bir tamsayıdır. Tüm girdilerin iyi oluşturulduğunu varsayabilirsiniz.
  2. Yönlendirme diyagramı çıktısı stdout'a gider.

    • 1'den n'ye kadar olan sayıları "düşürme" şemanın üstüne giriş permütasyonunun alttan çıkmasına neden olmalıdır. (Üst ve alt daima eğik çizgi katmanlarıdır.)
    • Diyagramın optimal olarak küçük olması gerekmez. Doğru olduğu sürece gerektiği kadar seviye olabilir.
    • Diyagram yalnızca karakterleri içermelidir \/ X| yanı sıra yeni satırları da (sayı yok).
    • |her zaman en dış kavşaklarda kullanılmalıdır, çünkü kullanımı Xmantıklı değildir.
    • Diyagramın tamamı doğru bir şekilde sıralandığı sürece birkaç ön veya arka boşluk iyi olur.

Örnekler

Üretebilecek bir girdi 3 1 4 2(yukarıdaki ile aynı)

 \ / \ /
  |   | 
 / \ / \
|   X   |
 \ / \ /
  X   X 
 / \ / \

Bir giriş 1kudreti üretmek

 \
  |
 /
|
 \
  |
 /

Bir giriş 3 2 1kudreti üretmek

 \ / \
  X   |
 / \ /
|   X
 \ / \
  X   |
 / \ /

Bir giriş 2 1 3 4 6 5kudreti üretmek

\ / \ / \ /
 X   |   X
/ \ / \ / \

4
Harika bir soru! Katılmanın sadece iki hafta geçtiğine inanamıyorum - her yerde gibisin.
xnor

@xnor: D Teşekkürler. Ama gerçekten burada çok fazla zaman geçiriyorum ...
Calvin'in Hobileri

Bir Xbağlantı bir |yolla doğrudan bağlanabilir /mi? Bir başkasına X?
xnor

1
@xnor sayılı Hep olmalıdır row of slashes, row of X's and |'s, row of slashes, row of X's and |'s, ... biçiminde.
Calvin'in Hobileri

n10'dan büyük olabilir mi?
Οurous

Yanıtlar:


4

Python 2, 218 219 220 222 224 227 243 247 252 259 261 264

l=map(int,raw_input().split())
f=n=len(l)
o=s=n*' \ /'
while f+n%2:
 f-=1;i=f+n&1;a=s[2*i:][:2*n]+'\n|   '[::2-i]
 while~i>-n:a+='|X'[l[i+1]<l[i]]+'   ';l[i:i+2]=sorted(l[i:i+2]);i+=2
 o=a+f%2*'|'+'\n'+o
print o[:-2*n]

Biraz farklı bir yaklaşım izledim: Girdiyi sıralamak için gerekli olan takasları buluyorum, sonra sıralı listeyi girdiye dönüştürmek için gereken takasları elde etmek için dikey olarak ters çeviriyorum. Bu yaklaşımın bir avantajı olarak, rastgele bir sayı listesi alabilir ve girdinin türünü girdiye dönüştürmek için permütasyon yolu verebilir.

Örnek:

$ python sort_path.py <<< '3 1 4 5 9 2 6 8 7'
 \ / \ / \ / \ / \
  |   |   |   |   |
 / \ / \ / \ / \ /
|   |   |   |   |   
 \ / \ / \ / \ / \
  |   |   |   |   |
 / \ / \ / \ / \ /
|   |   |   |   |   
 \ / \ / \ / \ / \
  |   |   |   |   |
 / \ / \ / \ / \ /
|   X   |   |   X   
 \ / \ / \ / \ / \
  |   X   |   X   |
 / \ / \ / \ / \ /
|   |   X   X   |   
 \ / \ / \ / \ / \
  X   |   X   |   |
 / \ / \ / \ / \ /
|   |   |   |   X   
 \ / \ / \ / \ / \

İyileştirmeler:

264 -> 261: Dış halkayı saatten ikiye değiştirdi.

261 -> 259: Kullanılmış f%2yerine(c^m) , çünkü python'da aritmetik işleçler bitsel operatörlerden daha yüksek önceliğe sahiptir.

259 -> 252: İç döngü için süre modunu değiştirdi. Kombine ivec değişkenler.

252 -> 247: İnşa değiştirildi, sonra tersine inşa edilmek için tersine çevrildi.

247 -> 243: Birleştirme kullanmak yerine elle yeni satırlar eklendi.

243 -> 227: GRC'nin eğik çizgi oluşturma yöntemi benimsendi (teşekkürler grc!) Ve s eklendi.

227 -> 224: Bir dilimi kaldırmak %4ve genişletilmiş dilimleme kullanarak bir karakteri kaydetmek için eğik çizgi oluşturma işlemini iç while döngüsünden önce taşıdı.

224 -> 222: Kaldırıldı m.

222 -> 220: f%2+n%2 ->f+n&1

220 -> 219: | 1<n-1|->|~i>-n| (ön boşluk kaldırıldı)

219 -> 218: ve öğelerinin birlikte başlatılması ove sdilimin sonuna kadar taşınması.


9

Python, 290

def g(o,u=1):
 s=['|']*o
 for i in range(o,n-1,2):v=r[i+1]in a[:a.index(r[i])]*u;s+=['|X'[v]];r[i:i+2]=r[i:i+2][::1-2*v]
 print'  '*(1-o)+'   '.join(s+['|']*(o^n%2))*u+'\n'*u+(' / \\'*n)[2*o:][:n*2]
a=map(int,raw_input().split())
n=len(a)
r=range(1,n+1)
o=1
g(1,0)
g(0)
while r!=a:g(o);o^=1

Oldukça basit bir yaklaşıma gittim, ama umduğumdan biraz daha uzun sürdü. Listeyi çiftler halinde ele alır ve her bir çifti değiştirip değiştirmemeye karar verir. Liste girişle eşleşene kadar bu kesişen her satır için tekrarlanır.

Örnek:

$ python path.py
5 3 8 1 4 9 2 7 6
 \ / \ / \ / \ / \
  |   |   |   X   |
 / \ / \ / \ / \ /
|   X   X   X   X
 \ / \ / \ / \ / \
  X   X   X   X   |
 / \ / \ / \ / \ /
|   X   X   |   X
 \ / \ / \ / \ / \
  X   X   X   |   |
 / \ / \ / \ / \ /
|   |   |   X   |
 \ / \ / \ / \ / \

2

HTML JavaScript, 553 419

Hatalarımı işaret ettiğiniz için @izlin ve @TomHart'a teşekkür ederim.

p=prompt();b=p.split(" "),l=b.length,d=l%2,o="",s=["","","\\/"],n="\n",a=[];for(i=0;i<l;i++){a[b[i]-1]=i+1;s[1]+=" "+s[2][i%2];s[0]+=" "+s[2][(i+1)%2];o+=" "+(i+1)}s[1]+=n,s[0]+=n;o+=n+s[1];f=1,g=2;do{var c="";for(var i=(f=f?0:1);i<l-1;i+=2)if(a[i]>a[i+1]){c+="  x ";g=2;t=a[i];a[i]=a[i+1];a[i+1]=t;}else c+="  | ";if(g==2){o+=(d?(f?"| "+c:c+"  |"):(f?"| "+c+"  |":c))+n;o+=(s[f]);}}while(--g);o+=" "+p;alert(o);

Burada test edin : http://goo.gl/NRsXEj
resim açıklamasını buraya girin resim açıklamasını buraya girin


Küçük bir hata yaptınız: ilk satır, sıralanan sayılar olmalı ve son satır, yukarıdaki örneklerde olduğu gibi sizin girdiniz olmalıdır.
izlin

Haklısın. Teşekkürler. @ Grc çıktısına baktım ve sayıların başlangıç ​​pozisyonu olduğunu düşündüm. Hata.
JeffSB

Buna yanlış bakıyordum, ama her iki resimde de, son satır hiçbir şey değişmediği için gereksiz değil mi?
TMH

Evet haklısın. Bunun nasıl yaptığım konusunda fikir birliği olduğunu biliyordum. Ama muhtemelen olmak zorunda değil. Bunu düşüneceğim. Yorum için teşekkürler.
JeffSB

@izlin - Bunu fark ettiğiniz için teşekkürler. Bu hatayı düzelttim.
JeffSB

1

Javascript - 395

378 çıkışımdaki sayıları yazdırmazsam, ancak çok daha iyi görünür ve okunabilirliği artırır.
Burada test edin . (ungolfed versiyonu ile)

golfed Sürüm:

a=prompt(),n=a.split(" "),l=n.length,k=[],s="",i=1;for(j=0;j<l;j++){k[n[j]-1]=j+1;s+=" "+(j+1)}s+="\n";while(i++){for(j=0;j<l;j++)s+=i%2?j%2?" \\":" /":j%2?" /":" \\";for(z=0,y=0;z<l-1;z++)if(k[z]>k[z+1])y=1;if(y==0&&i!=2)break;s+="\n";for(m=i%2;m<l;m+=2){s+=i%2&&m==1?"|":"";if(k[m]>k[m+1]){[k[m],k[m+1]]=[k[m+1],k[m]];s+=i%2?"   X":"  X "}else{s+=i%2?"   |":"  | "}}s+="\n"}s+="\n "+a;alert(s)

açıklama

Önce girdiyi dizin numarasıyla değiştiriyorum ve ilk satırı sonuçlarla değiştiriyorum. Örneğin

3 1 4 2
v v v v substitude with
1 2 3 4

so the first line will become:
1 2 3 4
v v v v
2 4 1 3

sorting 1,2,3,4 to 3,1,4,2 is equivalent to 2,4,1,3 to 1,2,3,4

Bu ikame ile, 2,4,1,3 ila 1,2,3,4'ü sıralamak için bir kabarcık sıralama algoritması kullanabilirim ve grafik, aradığımız en kısa grafik olacak.
Eğer nasıl kod daha küçük yapabilirim hakkında herhangi bir fikriniz varsa sadece yorum :)

Misal

input: 3 4 2 1 7 5 6
output:
 1 2 3 4 5 6 7
 \ / \ / \ / \
  X   |   |   | 
 / \ / \ / \ /
|   X   |   X
 \ / \ / \ / \
  X   X   X   | 
 / \ / \ / \ /
|   X   |   |
 \ / \ / \ / \
 3 4 2 1 7 5 6


(1) BR etiketini üç yerde kullandığınızı görüyorum ve böylece bunu bir değişkene koyarak biraz tasarruf edebilirsiniz. Ayrıca, bir PRE'ye çıkışınızdan bu yana \ n kullanabilirsiniz.
JeffSB

(2) Golf JavaScript ile başa çıkmak için farklı yollar denedim ve aynı zamanda uygun giriş ve çıkışa sahip oldum. Ben senin istemi ve uyarı esinlenerek benim son yöntem gibi düşünüyorum ... Ben bir konsola yapıştırılabilir böylece kod istemi ve uyarı kullanın ve herkes için çalışır. Ama aynı zamanda TEXTAREA ve PRE ile çalıştığını göstermek için bir web sayfası yaptım. Web sayfası, TEXTAREA ve PRE'yi kullanmak için istemi ve uyarıyı geçersiz kılar - bu yüzden aynı kod ve daha az karışıklık var - belki?
JeffSB

@JeffSB <br>Etiketi ve textarea'yı yalnızca jsfiddle'da kullandım, çünkü çok daha iyi görünüyor. Uyarının tek aralıklı yazı tipi yoktur, bu nedenle çıktı kötü görünür. Golf Sürümünde uyarı kullanıyorum ve \ n. Web sayfanız herkese açık mı?
izlin

1

Cobra - 334 344 356 360

class P
    def main
        a,o,n=CobraCore.commandLineArgs[1:],['/','\\'],0
        c,l=a.count,a.sorted
        while (n+=1)%2or l<>a
            p,d='',(~n%4+4)//3
            for i in n%2*(c+1-c%2),p,o=p+o[1]+' ',[o.pop]+o
            for i in 1+d:c-n%2*c:2
                z=if(l[:i]<>a[:i],1,0)
                l.swap(i-z,i)
                p+=' ['|X'[z]]  '
            print[['','| '][d]+[p,p+'|'][d^c%2],p][n%2][:c*2]

Her elemanı soldan başlayarak yerine taşıyarak çalışır. Bu nedenle, genellikle gülünç derecede büyük (hala doğru olmasına rağmen) bir yol haritası çıkarır.

Örnekler:

3 1 4 2

\ / \ / 
 X   X  
/ \ / \ 
|  X  |
\ / \ / 
 X   X  
/ \ / \ 
|  X  |
\ / \ / 
 X   X  
/ \ / \ 
|  X  |
\ / \ / 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.