Disegna un percorso di permutazione


20

Immagina i seguenti diagrammi come set di tubi verticali incrociati.

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

Nel diagramma più a sinistra, il 1 e 2far scorrere verso il basso le rispettive barre, attraversare il X, ed uscire dai lati opposti da dove sono partiti.

È la stessa idea nel diagramma centrale, ma il | indica che i percorsi non si incrociano, quindi non cambia nulla.

Il diagramma più a destra mostra un percorso del tubo più complesso che lo consente 1 2 3 4 in 3 1 4 2.

Obbiettivo

Il tuo obiettivo in questa sfida di golf del codice è di disegnare questi "diagrammi di instradamento del tubo" dati una permutazione come 3 1 4 2. Vincerà il programma più breve in byte.

Dettagli

  1. L'input proviene da stdin come qualsiasi permutazione dei numeri da 1 a n separati da spazi, dove n è un numero intero positivo. Si può presumere che tutti gli input siano ben formati.
  2. L'output del diagramma di routing passa a stdout.

    • "Rilasciare" i numeri da 1 a n in ordine nella parte superiore del diagramma dovrebbe provocare la permutazione dell'ingresso in basso. (Superiore e inferiore sono sempre strati di barre.)
    • Il diagramma non deve essere ottimamente piccolo. Può essere il numero di livelli necessario purché sia ​​corretto.
    • Il diagramma deve contenere solo i caratteri \/ X| e le nuove righe (nessun numero).
    • | dovrebbe sempre essere usato sulle intersezioni più esterne dall'uso X non avrebbe senso.
    • Alcuni spazi iniziali o finali vanno bene purché il diagramma sia allineato correttamente.

Esempi

Un input di 3 1 4 2potrebbe produrre (come sopra)

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

Un input di 1potrebbe produrre

 \
  |
 /
|
 \
  |
 /

Un input di 3 2 1potrebbe produrre

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

Un input di 2 1 3 4 6 5potrebbe produrre

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

4
Ottima domanda! Non riesco a credere che tu abbia aderito solo due settimane - sembra che tu sia ovunque.
xnor

@xnor: D Grazie mille. Ma davvero ho passato troppo tempo qui ...
Hobby di Calvin il

Può Xconnettersi direttamente al |modo in cui lo /fa? A un altro X?
xnor

1
@xnor No. Dovrebbe essere sempre in row of slashes, row of X's and |'s, row of slashes, row of X's and |'sformat, ....
Calvin's Hobbies,

Può nessere maggiore di 10?
Οuroso

Risposte:


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]

Ho adottato un approccio leggermente diverso: trovo gli swap necessari per ordinare l'input, quindi capovolgo verticalmente quello per ottenere gli swap necessari per trasformare l'elenco ordinato in input. Come ulteriore vantaggio di questo approccio, può essere necessario un elenco arbitrario di numeri e fornire il percorso di permutazione per trasformare il tipo di input nell'input.

Esempio:

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

miglioramenti:

264 -> 261: anello esterno commutato da per a mentre.

261 -> 259: utilizzato f%2invece di (c^m), perché in Python gli operatori aritmetici hanno una priorità maggiore rispetto agli operatori bit a bit.

259 -> 252: loop interno commutato da per a mentre. Combinato iec variabili.

252 -> 247: build modificata, quindi invertire per creare solo in ordine inverso.

247 -> 243: aggiunte nuove righe manualmente, anziché utilizzare join.

243 -> 227: Adottato il metodo di grc per la generazione della barra (grazie a grc!) E aggiunto s.

227 -> 224: spostata la generazione della linea di taglio prima del ciclo while interno per rimuovere a %4 e salvare un personaggio usando lo slicing esteso.

224 -> 222: rimosso m.

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

220 -> 219: | 1<n-1|->|~i>-n| (spazio iniziale rimosso)

219 -> 218: inizializzazioni combinati di oe se si è trasferito la fetta fino alla fine.


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

Ho optato per un approccio abbastanza semplice, ma è risultato un po 'più lungo di quanto sperassi. Considera l'elenco in coppie e decide se scambiare o meno ciascuna coppia. Questo viene ripetuto per ogni riga intersecante fino a quando l'elenco corrisponde all'input.

Esempio:

$ 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

Grazie a @izlin e @TomHart per aver segnalato i miei errori.

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);

Prova qui: http://goo.gl/NRsXEj
inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine


Hai fatto un piccolo errore: la prima riga dovrebbe essere i numeri ordinati e l'ultima riga dovrebbe essere il tuo input come negli esempi sopra.
izlin,

Hai ragione. Grazie. Ho guardato l'output di @ grc e ho pensato che i numeri fossero la posizione iniziale. Ops.
JeffSB,

Potrei guardare questo errore, ma in entrambe le foto che hai pubblicato, l'ultima riga non è ridondante in quanto non cambia nulla?
TMH,

Si hai ragione. Sapevo che questo era un consenso su come l'ho fatto. Ma probabilmente non deve esserlo. Ci penserò. Grazie per il commento.
JeffSB,

@izlin - Grazie per averlo notato. Ho corretto questo errore.
JeffSB,

1

Javascript - 395

378 se non stampo i numeri sul mio output, ma sembra molto meglio e migliora la leggibilità.
Provalo qui . (con versione non golfata)

Versione golfizzata :

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)

Spiegazione

Per prima cosa sostituisco l'input, con il numero di indice e cambio la prima riga con i risultati. Per esempio

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

Con questa sostituzione posso usare un algoritmo di ordinamento a bolle per ordinare da 2,4,1,3 a 1,2,3,4 e il grafico sarà il più breve possibile che stiamo cercando.
Se hai idee su come posso ridurre il codice basta commentare :)

Esempio

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) Vedo che usi il tag BR in tre punti, e quindi potresti risparmiare un po 'inserendolo in una variabile. Inoltre potresti probabilmente usare \ n dal momento in cui hai emesso un PRE.
JeffSB,

(2) Ho provato diversi modi per gestire il golf JavaScript e anche avere input e output convenienti. Penso che mi piace il mio ultimo metodo ispirato al tuo prompt e avviso ... Uso prompt e avviso nel codice in modo che possa essere incollato in una console e funziona per chiunque. Ma ho anche creato una pagina web con un TEXTAREA e PRE per dimostrarlo funzionante. La pagina Web ignora il prompt e l'avviso per utilizzare TEXTAREA e PRE - quindi è lo stesso codice e c'è meno confusione - forse?
JeffSB,

@JeffSB Ho usato il <br>tag e textarea solo su jsfiddle, perché sembra molto meglio. L'avviso non ha un carattere a spaziatura fissa, quindi l'output sembra scadente. Nella mia versione golfata uso alert e \ n. La tua pagina web è pubblica?
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]

Funziona spostando ogni elemento in posizione a partire da sinistra. Per questo motivo, genererà spesso una mappa del percorso ridicolmente grande (anche se ancora corretta).

Esempi:

3 1 4 2

\ / \ / 
 X   X  
/ \ / \ 
|  X  |
\ / \ / 
 X   X  
/ \ / \ 
|  X  |
\ / \ / 
 X   X  
/ \ / \ 
|  X  |
\ / \ / 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.