Problema
Supongamos que tiene N pilas llamadas S 1 a S N , donde cada S k (k = 1 a N) contiene N copias del número k.
Por ejemplo, cuando N = 3 las pilas se ven así:
1 2 3 <- top of stack
1 2 3
1 2 3 <- bottom of stack
=======
1 2 3 <- stack index
Aquí hay 3 pilas indexadas como 1, 2 y 3, y cada una contiene N instancias de su propio índice.
El objetivo es reorganizar las N pilas de modo que cada una de ellas contenga idénticamente los números del 1 al N en orden de arriba a abajo.
Por ejemplo, para N = 3, el objetivo es reorganizar las pilas en:
1 1 1
2 2 2
3 3 3
=======
1 2 3
La única acción que puede realizar con las pilas es tomar el número superior de una de las pilas (estallar) e inmediatamente colocarlo encima de una pila diferente (empujar) . Esto está sujeto a estas estipulaciones:
Un número solo se puede insertar en una pila si es menor o igual que el número superior en esa pila.
por ejemplo, a
1
se puede empujar a una pila con a1
,2
o3
en la parte superior, pero a2
solo se puede empujar a una pila con a2
o3
(o más alto) en la parte superior.Esto tiene el efecto de que las pilas siempre están aumentando monotónicamente de arriba a abajo.
Se puede extraer cualquier pila no vacía y, suponiendo que se satisfaga la viñeta anterior, se puede empujar a cualquier pila.
Cualquier número puede ser empujado a una pila vacía.
Las pilas no tienen límite de altura máxima.
Las pilas no se pueden crear ni destruir, siempre hay N de ellas.
Este desafío se trata de decidir qué pops y empujes hacer para completar el intercambio de stack, no necesariamente en la menor cantidad de movimientos, sino de una manera segura.
(Practicar con una baraja de cartas es una buena manera de tener una idea del problema).
Reto
Escriba un programa o función que tome un entero positivo N, garantizado como 3 o superior. Imprima o devuelva una cadena que denote todas las acciones de empuje emergente necesarias para reorganizar las pilas desde el estado inicial:
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
=============
1 2 3 4 5
(N = 5 caso)
Al estado final:
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5
=============
1 2 3 4 5
Cada línea en su salida debe contener dos números separados por un espacio. El primer número es el índice de la pila a partir de la cual saltar y el segundo número es el índice de la pila a empujar. Realizar las acciones de todas las líneas en orden debe organizar las pilas correctamente sin romper ninguna regla.
Por ejemplo, aquí hay una salida válida potencial para el caso N = 3:
1 2 [move the top number on stack 1 to the top of stack 2]
1 2 [repeat]
1 2 [repeat]
3 1 [move the top number on stack 3 to the top of stack 1]
2 3 [etc.]
2 3
2 3
2 1
2 1
2 1
3 1
3 1
3 1
3 2
1 2
1 2
1 2
1 3
2 3
2 3
2 3
1 2
3 2
3 1
Notas
Su salida no necesita ser óptima , solo correcta. es decir, no necesita minimizar la cantidad de pops y empujones.
- Por lo tanto, estaría bien si, por ejemplo, se hiciera algún movimiento repetidamente y se invirtiera de inmediato.
- Hacer estallar y empujar a la misma pila en un solo movimiento, por ejemplo
2 2
, también está permitido (aunque, por supuesto, no tiene sentido).
Su salida hace necesidad de ser determinista y finito.
Recuerde que las pilas tienen indexación basada en 1. La indexación basada en 0 no está permitida.
N mayor que 9, por supuesto, debería funcionar tan bien como un solo dígito N.
Si lo desea, puede usar dos caracteres ASCII imprimibles distintos que no sean dígitos en lugar de espacios y líneas nuevas. Una nueva línea final (o un sustituto de nueva línea) en la salida está bien.
Tanteo
El código más corto en bytes gana. Tiebreaker es la respuesta más votada.
Puntos brownie sin valor si puede mostrar que su algoritmo es óptimo.
fuente
-._(._.)_.-
N=3
óptimo?Respuestas:
Pyth
9694 bytesPruébalo aquí
¿Como funciona?
Esta explicación usará N = 5.
Parte 1: crea la capa inferior en cada pila
La razón por la que esto necesita un código separado es porque cada pila necesita ser utilizada: los primeros 4 necesitan que se coloque un 5 debajo de ellos, y la última pila debe proporcionar los 5. Esto significa que no podemos mover todos los 4 en algún lugar, poner un 5 allí y mover los 4 hacia atrás.
Visualización: (los paréntesis significan lo que se moverá)
En cambio, para hacer este primer intercambio, primero vamos a mover todos los 1s a la segunda pila, mover un 5 a la primera pila (que ahora está vacía), mover los 1s a la tercera pila, mover los 2s a la primera apilar, mover los 1s a la primera pila y finalmente mover un 5 a la segunda pila.
Ahora que tenemos un espacio libre para mover las pilas (pila 2, que solo contiene un 5 que se coloca en el lugar correcto), podemos mover todos los 3 a la pila 2 y colocar un 5 en la pila 3. Luego podemos repetir ¡Lo mismo para la pila 4, y ahora tenemos todos los 5 en el lugar correcto! Y solo una cosa más: moveremos todos los 1s al stack 5 para que tengamos una buena configuración para el próximo intercambio de stack.
Parte 2: Haz todo lo demás :)
Esto es mucho más fácil ahora, porque ahora siempre tendremos una pila libre para mover otros números con los que debemos hacer malabarismos. Entonces, primero descubrimos dónde está el 4. Un poco de examen mostrará que siempre estará 1 arriba de donde comenzó, o 2 arriba de la última pila. Ahora, seguimos bajando por las pilas, colocando un 4 en la pila si está libre, o subiendo los otros números 1 pila si no lo está. Ahora tenemos todos los 4 en su lugar.
Ahora, nos damos cuenta de que los 3 son 2 pilas por encima de donde están los 4. ¡Esto significa que podemos hacer exactamente lo mismo que hicimos con los 4s! Y resulta que podemos seguir haciéndolo siempre que envuelvamos el índice de la pila al otro lado.
Y así, podemos seguir haciendo esto hasta que hayamos intercambiado todas las pilas.
Explicación del código:
En primer lugar: las variables (importantes) predefinidas.
Hay 2 definiciones lambda.
El intercambio de la pila: parte 1
El intercambio de la pila: parte 2
Ya sé que no estoy obteniendo puntos de brownie, porque puedo ver muchos métodos más eficientes y más complicados :(
fuente