Scambio di numeri [chiuso]


10

Questo è un puzzle comune che molti di voi hanno risolto manualmente. Ora è il momento di scrivere un algoritmo per risolvere lo stesso.

Ci sono levette uguali di numero allineate in due lati diversi rivolti l'uno verso l'altro. C'è un solo spazio vuoto tra di loro. Pronuncia qualcosa come la seguente figura (se il numero totale di stick di corrispondenza è 4).

inserisci qui la descrizione dell'immagine

Ogni stick può scorrere di un passo in avanti (se lo spazio frontale immediato è libero), oppure può essere saltato su uno stick davanti e atterrare nello spazio libero (se quello spazio è libero). Lo spostamento nella direzione opposta non è possibile (anche lo spazio è libero). Non è inoltre consentito il salto inverso. È consentita una sola mossa in una fase.

Ora, devi scrivere un algoritmo per trovare i passaggi minimi richiesti utilizzando i quali tutti gli stick di corrispondenza sul lato sinistro atterreranno sul lato destro e tutti gli stick di corrispondenza sul lato destro atterreranno sul lato sinistro.

Ad esempio: se ci sono 2 bastoncini (1 per lato) in totale, i passaggi saranno:

inserisci qui la descrizione dell'immagine

Nota: nella figura sopra la levetta laterale sinistra è stata spostata per prima. Un'altra soluzione esiste quando la levetta laterale destra si sposta per prima. Ma per questo problema, devi dare solo una soluzione e questo presuppone anche che la levetta laterale sinistra si muova per prima.

La figura seguente descrive le mosse con 4 levette (2 per lato):

inserisci qui la descrizione dell'immagine

Nota: nella figura sopra la levetta laterale sinistra è stata spostata per prima. Un'altra soluzione esiste quando la levetta laterale destra si sposta per prima. Ma per questo problema, devi dare solo una soluzione e questo presuppone anche che la levetta laterale sinistra si muova per prima.

[Presupposto: l'ingresso può essere un numero pari compreso tra 02 e 14 (ovvero da 1 a 7 stick di corrispondenza su ciascun lato). Per input al di fuori di questo intervallo, non è necessario eseguire alcuna convalida, né fornire alcun messaggio di errore. Nota: nell'output, ogni passaggio è separato da un '|' carattere (pipe). I programmatori COBOL devono sempre assumere PIC 9 (2) come dimensione di input e possono anche ritenere che l'output abbia una lunghezza massima di 450 caratteri, riempita con spazi a destra.]


Input di esempio:

02  

Uscita campione:

01To02|03To01|02To03|


Input di esempio:

04  

Uscita campione:

02To03|04To02|05To04|03To05|01To03|02To01|04To02|03To04|


Input di esempio:

06  

Uscita campione:

03To04|05To03|06To05|04To06|02To04|01To02|03To01|05To03|07To05|06To07|04To06|02To04|03To02|05To03|04To05|

Se non puoi includere direttamente le immagini, puoi fornire link a qualcun altro in cui modificarle?
Peter Taylor,

2
Ho fatto alcune immagini veloci. Speriamo che siano conformi alle intenzioni dell'autore originale.
primo

3
Condizioni per la vittoria?
Shmiddty,

Risposte:


3

129 APL

Il codice seguente accetta l'input e l'output dello schermo nel formato specificato:

n←n,n++\1↓z←(⌽z),((¯1*~2|n)×n⍴2),z←⌽∊(¯1*2|⍳n)ר1,((⍳(n←.5×⍎⍞)-1)⍴¨2),¨1⋄(∊(((¯2↑¨'0',¨⍕¨n),¨⊂'To'),¨(¯2↑¨'0',¨⍕¨n-z)),¨⊂'|')~' '

Un buon terzo del codice è occupato per la formattazione dell'output. La logica è completa dal verificarsi del simbolo ⋄ nel codice.

Di seguito è riportato il risultato per un input di 08 come controllo:

04To05|06To04|07To06|05To07|03To05|02To03|04To02|06To04|08To06|09To08|07To09|05To07|03To05|01To03|02To01|04To02|06To04|08To06|07To08|05To07|03To05|04To03|06To04|05To06|

1
Ho sempre la sensazione che APL stia tradendo>. <
Shmiddty,

@Shmiddty Temo che qualsiasi linguaggio basato esclusivamente su simboli come APL, J, GolfScript ecc. Molto probabilmente vincerà il golf del codice contro linguaggi più prolissi basati su parole;)
Graham

3

Javascript 178 174 161

prompts per la risposta nallora alerts. (Nessuna 0imbottitura)

Ultimo:

t=1+(m=prompt(s=i='')/2);for(z=Math.abs;i++<m*2;)for(j=m-z(m-i),s+=(t+=a=(m%2^z(m+.5-i)%2-.5)*-2+1)+'To'+(t-a)+'|';j--;)s+=(t+=a=i%2*4-2)+'To'+(t-a)+'|';alert(s)

2:

z=Math.abs;t=m=prompt(o=[])/2;t++;for(s=i='';i++<m*2;)for(j=m-z(m-i),o.push((z(m+.5-i)%2-.5)?-1:1);j--;)o.push(i%2?2:-2);o.map(function(a){s+=(t+=a)+'To'+(t-a)+'|'});alert(s)

1:

t=m=prompt(o=[])/2+1;for(s=i='';++i<m;)for(j=i,o.push(i%2?-1:1);j--;)o.push(i%2?2:-2);o.concat(o.slice().reverse().slice(m-1)).map(function(a){s+=(t+=a)+'To'+(t-a)+'|'});alert(s)

Questo utilizza il concetto che il modello è speculare:

Key
R='Jump Right'
r='Shift Right'
L='Jump Left'
l='Shift Left'
m='Move'
j='Jump'

Quindi, dove n=2, il modello di movimento è:

rLr
mjm

Il che equivale a

+1 -2 +1

Questo modello si ripete in questo modo ( n=8)

rLlRRrLLLlRRRRlLLLrRRlLr
mjmjjmjjjmjjjjmjjjmjjmjm
+1 -2 -1 +2 +2 +1 -2 -2 -2 -1 +2 +2 +2 +2 -1 -2 -2 -2 +1 +2 +2 -1 -2 +1

Possiamo notare alcuni schemi qui:

  1. Il movimento si alterna tra sinistra e destra
  2. Il numero di movimenti in una particolare direzione aumenta da 1 a n/2, che si ripete 3 volte, quindi diminuisce nuovamente a 1.
  3. Il tipo di movimento si alterna tra spostamento e salto, il numero di turni di fila è una costante 1e il numero di salti sequenziali aumenta da 1 a n/2poi diminuisce nuovamente a 1.
  4. La somma dei movimenti è sempre 0. (Non sono sicuro che questo sia effettivamente rilevante)

n=14:

rLlRRrLLLlRRRRrLLLLLlRRRRRRrLLLLLLLrRRRRRRlLLLLLrRRRRlLLLrRRlLr
mjmjjmjjjmjjjjmjjjjjmjjjjjjmjjjjjjjmjjjjjjmjjjjjmjjjjmjjjmjjmjm

Uscita campione:

f(2):

1To2|3To1|2To3| 

f(8):

4To5|6To4|7To6|5To7|3To5|2To3|4To2|6To4|8To6|9To8|7To9|5To7|3To5|1To3|2To1|4To2|6To4|8To6|7To8|5To7|3To5|4To3|6To4|5To6|

f(40):

20To21|22To20|23To22|21To23|19To21|18To19|20To18|22To20|24To22|25To24|23To25|21To23|19To21|17To19|16To17|18To16|20To18|22To20|24To22|26To24|27To26|25To27|23To25|21To23|19To21|17To19|15To17|14To15|16To14|18To16|20To18|22To20|24To22|26To24|28To26|29To28|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|12To13|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|31To30|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|10To11|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|33To32|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|8To9|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|35To34|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|6To7|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|37To36|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|4To5|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|39To38|37To39|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|3To5|2To3|4To2|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|40To38|41To40|39To41|37To39|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|3To5|1To3|2To1|4To2|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|40To38|39To40|37To39|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|3To5|4To3|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|37To38|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|6To5|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|35To36|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|8To7|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|33To34|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|10To9|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|31To32|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|12To11|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|29To30|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|14To13|16To14|18To16|20To18|22To20|24To22|26To24|28To26|27To28|25To27|23To25|21To23|19To21|17To19|15To17|16To15|18To16|20To18|22To20|24To22|26To24|25To26|23To25|21To23|19To21|17To19|18To17|20To18|22To20|24To22|23To24|21To23|19To21|20To19|22To20|21To22|

Ecco alcuni pseudo-codice per dimostrare il metodo:

var mid=cursor=N/2,delta
cursor++                 // the cursor is where the empty space is.
for(i=0; i++<N;){
  delta = (mid%2^abs(mid+.5-i)%2-.5)*-2+1;  // 1 or -1
  print((cursor+delta) + 'To' + cursor + '|')
  cursor+=delta
  for(j=mid-abs(mid-i);j--;)
  {
    delta = i%2*4-2  // 2 or -2
    print((cursor+delta) + 'To' + cursor + '|')
    cursor+=delta
  }
}

2
Hai ragione che lo schema è più chiaro con l/L/r/Re m/j. Mi piace l'idea di separare la distanza spostata dalla direzione
Gordon Bailey il

2

C - 216 213

La mia soluzione si basa su due fatti:

  1. Il campo "a" è il campo "da" della mossa precedente (poiché si crea sempre uno slot vuoto nello spazio da cui ci si sposta e ci si sposta sempre in uno slot vuoto)

  2. C'è un modello molto regolare per le distanze e le direzioni che vengono spostate. Per i primi 3 casi di test, sono:

    1 -2 1

    1 -2 -1 2 2 -1 -2 1

    1 -2 -1 2 2 1 -2 -2 -2 1 2 2 -1 -2 1

Con questo in mente ho praticamente scritto un programma per produrre e continuare quel modello. Sono abbastanza sicuro che ci debba essere un modo ricorsivo davvero bello e molto più elegante per scrivere questo, ma non l'ho ancora capito:

#include <stdio.h>

int main(int argc, const char *argv[])
{
   int upper_bound = atoi(argv[1]) / 2;
   int len;
   int from;
   int to = upper_bound + 1;
   int direction = 1;
   int i;

   for(len = 1; len <= upper_bound; ++len){
      for(i = len-1; i >=0; --i){
         from = to - direction*(1 + (i!=0));
         printf("%02dTo%02d|",from,to);
         to = from;
      }
      direction*=-1;
   }
   for(i=1; i < len; ++i){
      from = to - direction*2;
      printf("%02dTo%02d|",from,to);
      to = from;
   }
   direction*=-1;
   for(--len; len >= 0; --len){
      for(i = 0; i < len; ++i){
         from = to - direction*(1 + (i!=0));
         printf("%02dTo%02d|",from,to);
         to = from;
      }
      direction*=-1;
   }
   return 0;
}

E ho giocato a golf (anche se questa era una sfida al codice, non il golf):

#define B {F=T-D*(1+(i!=0));printf("%02dTo%02d|",F,T);T=F;}D*=-1;
L,F,T,D,i;main(int U,char**A){U=atoi(A[1])/2;T=U+1;D=1;for(L=1;L<=U;++L){for(i=L-1;i>=0;--i)B}for(i=1;i<L;++i)B for(--L;L>=0;--L){for(i=0;i<L;++i)B}}

#define B {F=T-D*(1+(i!=0));printf("%02dTo%02d|",F,T);T=F;}D*=-1;
L,F,T,D,i;main(int U){scanf("%d",&U);U/=2;T=U+1;D=1;for(L=1;L<=U;++L){for(i=L-1;i>=0;--i)B}for(i=1;i<L;++i)B for(--L;L>=0;--L){for(i=0;i<L;++i)B}}

Quando eseguo la tua versione da golf, ricevo un segfault.
artistoex,

Oh scusa, ho dimenticato di menzionare che l'input è dato come argomento della riga di comando - se lo esegui senza argomenti sarà segfault. Ma in realtà ora che me lo dici, non so perché pensassi che gli argomenti della riga di comando sarebbero stati più brevi di scanf. Sto aggiornando la mia risposta con una versione migliore.
Gordon Bailey,

Il modello è più evidente quando si utilizza L / R / L / R (grande essere "salto"): N(2)=rLr, N(4)=rLlRRlLr, N(6)=rLlRRrLLLrRRlLr, ecc
Shmiddty

2

matematica

Questo approccio crea una Nestsequenza di dimensioni e direzione delle mosse, formattata come {fromPosition,toPosition}, a partire dalla posizione n, dove si nriferisce al numero di coppie di corrispondenze. Quindi Foldè la sequenza in una funzione che inizia con lo spostamento {n, n+1}.

z@n_:=(p=1;h@t_:=Append[{Table[2 (-1)^t,{t}]},{(-1)^(t+1)}];
k=Join[Reverse@Drop[#,n],#]&[Flatten@Nest[Prepend[#,h[p++]]&,{},n]];
Fold[Append[#,{#[[-1,1]]-#2,#[[-1,1]]}]&,{{n,n+k[[1]]}},Rest@k])

z[1]

{{1, 2}, {3, 1}, {2, 3}}


z[4]

{{4, 5}, {6, 4}, {7, 6}, {5, 7}, {3, 5}, {2, 3}, {4, 2}, {6, 4}, { 8, 6}, {9, 8}, {7, 9}, {5, 7}, {3, 5}, {1, 3}, {2, 1}, {4, 2}, {6, 4}, {8, 6}, {7, 8}, {5, 7}, {3, 5}, {4, 3}, {6, 4}, {5, 6}}


z[7]

{{7, 8}, {9, 7}, {10, 9}, {8, 10}, {6, 8}, {5, 6}, {7, 5}, {9, 7}, { 11, 9}, {12, 11}, {10,12}, {8, 10}, {6, 8}, {4, 6}, {3, 4}, {5, 3}, {7, 5}, {9, 7}, {11, 9}, {13, 11}, {14, 13}, {12, 14}, {10, 12}, {8, 10}, {6, 8} , {4, 6}, {2, 4}, {1, 2}, {3, 1}, {5, 3}, {7, 5}, {9, 7}, {11, 9}, { 13, 11}, {15, 13}, {14, 15}, {12, 14}, {10, 12}, {8, 10}, {6, 8}, {4, 6}, {2, 4}, {3, 2}, {5, 3}, {7, 5}, {9, 7}, {11, 9}, {13, 11}, {12, 13}, {10, 12} , {8, 10}, {6, 8}, {4, 6}, {5, 4}, {7, 5}, {9, 7}, {11, 9}, {10, 11}, { 8, 10}, {6, 8}, {7, 6}, {9, 7}, {8, 9}}


Visualizzazione degli swap

r, be osono immagini o una corrispondenza rossa, una corrispondenza blu e nessuna corrispondenza, rispettivamente.

fiammiferi

Di seguito viene formattato l'output da zper visualizzare gli swap con le corrispondenze.

swaps[n_]:=FoldList[Grid[{Permute[#[[1,1]],Cycles[{#2}]],Range[2n+1]}]&,
Grid[{Join[Table[r,{n}],{o},Table[b,{n}]],Range[2n+1]}],z[n]]

swapMatches[n_]:=Grid[Partition[swaps[n],2,2,1,""],Dividers->All]

swapsproduce un elenco di stati utilizzando le coppie ordinate di zcome comandi per consentire l'elenco iniziale e gli elenchi successivi.

swaps[1]

swaps1

swapMatches visualizza gli stati in una griglia.

swapMatches[2]

swaps2

swapMatches[3]

swaps3


0

Javascript 191

function f(N) {
    n=N>>=i=c=a='1';n++
    s=z='0'
    for(k=b='34';i<N;k=i%2?a+=z+z:b+='44',i++)c=k+c
    t=''
    i=N*(N+1)/2
    l=2*i+N
    for(;l;n+=(i>=1?r=c[i-1]:i<=-N?c[-i-N]:k[1])-2,t+=(s=n>9?'':z)+n+a+'|',--l,--i)a='To'+s+n
    return t
}

Personaggi contati usando grep =|tr -d \ |wc -c


1
Ciao e benvenuto su codegolf! Penso che troverai che la tua soluzione non produce l'output corretto per nessuno dei casi di test ( jsfiddle.net/SJwaU ). Per l'input 02, i valori sono corretti, ma manca il finale |. Per gli altri due casi, i valori sono molto lontani e anche la formattazione di 10è errata. Inoltre, non sei sicuro del tuo metodo di conteggio dei personaggi. Perché stai contando solo il corpo della funzione meno il ritorno?
Gordon Bailey,

@gordon Oops, mi sembra di aver fatto un errore nella mia più recente ottimizzazione. Grazie per averlo segnalato. Conto il corpo solo perché su un REPL è tutto ciò di cui hai bisogno. Ho messo la decorazione della funzione solo per comodità.
artistoex,

È necessario contare gli spazi bianchi pertinenti (ad es. Nuove righe) per il totale.
Shmiddty,

@shmiddty tr -d \ |wc -cprende in considerazione le nuove righe
artistoex,
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.