Intercambio de números [cerrado]

10

Este es un rompecabezas común que muchos de ustedes han resuelto manualmente. Ahora es el momento de escribir un algoritmo para resolver el mismo.

Hay palos de igual número alineados en dos lados diferentes uno frente al otro en dirección. Hay un solo espacio vacío entre ellos. Diga algo como la siguiente figura (si el número total de palos de coincidencia es 4).

ingrese la descripción de la imagen aquí

Cada palo puede deslizarse un paso hacia adelante (si el espacio frontal inmediato es libre), o puede saltarse sobre un palo en su frente y aterrizar en el espacio libre (si ese espacio es libre). El movimiento en dirección inversa no es posible (incluso el espacio es libre). No se permite el salto inverso también. Solo se permite un movimiento en un solo paso.

Ahora, tiene que escribir un algoritmo para encontrar los pasos mínimos requeridos con los cuales todos los palos de coincidencia del lado izquierdo caerán en el lado derecho y todos los palos de partido del lado derecho caerán en el lado izquierdo.

Por ejemplo: si hay un total de 2 palos (1 en cada lado), los pasos serán:

ingrese la descripción de la imagen aquí

Nota: En la figura anterior, la palanca lateral izquierda se movió primero. Existe otra solución cuando el palo del lado derecho se mueve primero. Pero para este problema, debe dar solo una solución y eso también supone que el joystick izquierdo se mueva primero.

La siguiente figura describe los movimientos con 4 palos (2 en cada lado):

ingrese la descripción de la imagen aquí

Nota: En la figura anterior, la palanca lateral izquierda se movió primero. Existe otra solución cuando el palo del lado derecho se mueve primero. Pero para este problema, debe dar solo una solución y eso también supone que el joystick izquierdo se mueva primero.

[Suposición: La entrada puede ser cualquier número par entre 02 y 14 (es decir, 1 a 7 palos coincidentes en cada lado). Para las entradas fuera de este rango, no necesita hacer ninguna validación, ni tampoco debe proporcionar ningún mensaje de error. Nota: en la salida, cada paso está separado por un '|' (pipa) personaje. Los programadores de COBOL siempre deben asumir PIC 9 (2) como tamaño de entrada y también pueden suponer que la salida tiene una longitud máxima fija de 450 caracteres, rellena con espacios a la derecha.]


Entrada de muestra:

02  

Salida de muestra:

01To02|03To01|02To03|


Entrada de muestra:

04  

Salida de muestra:

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


Entrada de muestra:

06  

Salida de muestra:

03To04|05To03|06To05|04To06|02To04|01To02|03To01|05To03|07To05|06To07|04To06|02To04|03To02|05To03|04To05|
usuario2076421
fuente
Si no puede incluir las imágenes directamente, ¿puede proporcionar enlaces para que otra persona las edite?
Peter Taylor
2
Hice algunas imágenes rápidas. Esperemos que se ajusten a la intención del autor original.
primo
3
Condición para la victoria?
Shmiddty

Respuestas:

3

APL 129

El siguiente código toma entradas y salidas de pantalla a la pantalla en el formato especificado:

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 buen tercio del código se toma formateando la salida. La lógica se completa por la aparición del símbolo ⋄ en el código.

A continuación se muestra el resultado de una entrada de 08 como verificación:

04To05|06To04|07To06|05To07|03To05|02To03|04To02|06To04|08To06|09To08|07To09|05To07|03To05|01To03|02To01|04To02|06To04|08To06|07To08|05To07|03To05|04To03|06To04|05To06|
Graham
fuente
1
Siempre siento que APL está haciendo trampa>. <
Shmiddty
@Shmiddty Me temo que cualquier lenguaje puramente basado en símbolos como APL, J, GolfScript, etc. probablemente ganará golf de código contra lenguajes más verbosos basados ​​en palabras;)
Graham
3

Javascript 178 174 161

prompts para nluego alerts respuesta. (Sin 0relleno)

Último:

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)

Esto utiliza el concepto de que el patrón se refleja:

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

Entonces, dónde n=2, el patrón de movimiento es:

rLr
mjm

Lo que equivale a

+1 -2 +1

Este patrón se repite así ( 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

Podemos notar algunos patrones aquí:

  1. El movimiento alterna entre izquierda y derecha
  2. El número de movimientos en una dirección particular aumenta de 1 a n/2, que se repite 3 veces, luego disminuye de nuevo a 1.
  3. El tipo de movimiento alterna entre cambios y saltos, el número de cambios seguidos es una constante 1y el número de saltos secuenciales aumenta de 1 a n/2luego disminuye de nuevo a 1.
  4. La suma de los movimientos es siempre 0. (No estoy seguro si esto es realmente relevante)

n=14:

rLlRRrLLLlRRRRrLLLLLlRRRRRRrLLLLLLLrRRRRRRlLLLLLrRRRRlLLLrRRlLr
mjmjjmjjjmjjjjmjjjjjmjjjjjjmjjjjjjjmjjjjjjmjjjjjmjjjjmjjjmjjmjm

Salida de muestra:

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|

Aquí hay un pseudocódigo para demostrar el método:

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
  }
}
Shmiddty
fuente
2
Tienes razón en que el patrón es más claro con l/L/r/Ry m/j. Me gusta la idea de separar la distancia movida de la dirección
Gordon Bailey
2

C - 216 213

Mi solución se basa en dos hechos:

  1. El campo "a" es el campo "desde" del movimiento anterior (ya que siempre crea un espacio vacío en el espacio desde el que se mueve y siempre se mueve a un espacio vacío)

  2. Hay un patrón muy regular en las distancias y direcciones que se mueven. Para los primeros 3 casos de prueba, son:

    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 eso en mente, básicamente escribí un programa para producir y continuar ese patrón. Estoy bastante seguro de que debe haber una forma recursiva realmente hermosa y mucho más elegante de escribir esto, pero aún no lo he descubierto:

#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;
}

Y golf (aunque este fue un desafío de código, no 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}}
Gordon Bailey
fuente
Cuando ejecuto su versión de golf, obtengo un segfault.
artistoex
Oh, lo siento, olvidé mencionar que la entrada se proporciona como un argumento de línea de comando; si lo ejecuta sin argumentos, se omitirá. Pero en realidad ahora que lo mencionas, no sé por qué pensé que los argumentos de la línea de comandos serían más cortos que scanf. Estoy actualizando mi respuesta con una versión mejor.
Gordon Bailey
El patrón es más notable cuando se utiliza I / D / L / R (ser grande "salto"): N(2)=rLr, N(4)=rLlRRlLr, N(6)=rLlRRrLLLrRRlLr, etc.
Shmiddty
2

Mathematica

Este enfoque crea una Nestsecuencia ed del tamaño y la dirección de los movimientos, formateada como {fromPosition,toPosition}, comenzando con la posición n, donde se nrefiere al número de pares de coincidencias. Luego Foldconvierte la secuencia en una función que comienza con el movimiento {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}}


Visualizando los Swaps

r, by oson imágenes o una coincidencia roja, una coincidencia azul y ninguna coincidencia, respectivamente.

partidos

A continuación, se formatea la salida zpara mostrar los intercambios con coincidencias.

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 una lista de estados utilizando los pares ordenados de zcomandos como para permutar la lista inicial y las listas posteriores.

swaps[1]

swaps1

swapMatches muestra los estados en una cuadrícula.

swapMatches[2]

swaps2

swapMatches[3]

swaps3

DavidC
fuente
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
}

Caracteres contados usando grep =|tr -d \ |wc -c

artistoex
fuente
1
Hola y bienvenido a codegolf! Creo que encontrará que su solución no produce la salida correcta para ninguno de los casos de prueba ( jsfiddle.net/SJwaU ). Para la entrada 02, los valores son correctos, pero le falta el final |. Para los otros dos casos, los valores están muy alejados, y el formato 10también es incorrecto. Tampoco estoy seguro sobre tu método de conteo de personajes. ¿Por qué solo cuenta el cuerpo de la función menos el retorno?
Gordon Bailey
@ gordon Vaya, parece que cometí un error en mi optimización más reciente. Gracias por señalar Cuento el cuerpo solo porque en un REPL, eso es todo lo que necesitas. He puesto la decoración de la función solo por conveniencia.
artistoex
Es necesario contar los espacios en blanco relevantes (por ejemplo, nuevas líneas) hacia su total.
Shmiddty
@shmiddty tr -d \ |wc -ctiene en cuenta las
nuevas líneas