Así es como rodamos

18

Piet es un lenguaje de programación interesante por varias razones. Hoy nos centraremos en una razón: el comando roll . El comando roll fue originalmente de PostScript y es una forma poderosa de manipular la pila.

El comando roll muestra los dos elementos superiores de la pila y los usa como parámetros. Llamaremos al primer valor reventado turnsy al segundo depth. Un giro hacia la profundidad n tomará el elemento superior de la pila, lo convertirá en el enésimo elemento de la pila y moverá cada uno de los elementos por encima de uno. Si turns es negativo, esto se hace en la dirección opuesta. Es decir, el enésimo elemento se mueve hacia arriba y los otros elementos se mueven hacia abajo. Esto se repite abs(turns)veces.

Desafío

Escriba un programa o función que tome una pila y la devuelva después de ejecutar un rollo.

Reglas

  • La entrada y salida pueden estar en una lista, matriz, cadena con un delimitador, pasado en un elemento a la vez, o cualquier otro formato razonable. La salida debe estar en el mismo formato que la entrada.
  • depth nunca será negativo y nunca será mayor que la longitud de la pila.
  • La pila de entrada siempre contendrá al menos dos elementos.
  • Este es el por lo que gana la respuesta más corta en cada idioma. Como tal, no aceptaré una respuesta.
  • Las lagunas estándar están prohibidas.

Casos de prueba

in:  out:
2    
4    
1    3
2    4
3    1
4    2
5    5
6    6

in:  out:
-2   
3
1    2
2    3
3    1

in:  out:
-42
0
1    1
2    2
3    3
4    4
5    5
Mike Bufardeci
fuente
2
la respuesta más corta en cada idioma gana , no es así como funciona [code-golf]. La respuesta más corta gana. Período.
mbomb007
44
@ mbomb007 ejem, ¿qué hay de esto
Christopher
77
Estaba muy decepcionado de que esto no implicara de ninguna manera el rodaje de rick
Christopher
2
@ mbomb007 No veo eso en la descripción de la etiqueta o en una búsqueda rápida en meta, así que no creo que sea el caso.
Mike Bufardeci
2
@ mbomb007 Si desea que lo cambie, proporcione algún tipo de argumento que no sea decir "está equivocado y tengo razón" una y otra vez. Hay un precedente para esto, que rechazaste, y en ninguna parte dice que los desafíos requieren exactamente un ganador o que se debe aceptar una respuesta.
Mike Bufardeci

Respuestas:

8

Haskell , 64 62 bytes

Editar: -2 bytes: @xnor vio algo en lo que había pensado mal.

rtoma y devuelve una lista de Ints.

r(t:d:l)|d<1=l|(x,y)<-d%l,(z,w)<-mod t d%x=w++z++y
(%)=splitAt

Pruébalo en línea!

splitAt n ldivide una lista len el índice n, modcalcula el resto de la división, ++concatena listas.

Ørjan Johansen
fuente
1
Creo que puedes cortar 2 bytes definiendo (%)=splitAtinfix.
xnor
@xnor Oh, de alguna manera me convencí de que no funcionaría
Ørjan Johansen
8

JavaScript (ES6), 49 47 bytes

(t,d,...a)=>a.splice(t=(t%d+d)%d,d-t).concat(a)

Editar: ahorró 2 bytes gracias a @Shaggy al tomar los elementos de la pila como parámetros separados. Explicación:

  • Cuando el giro es un múltiplo de la profundidad, no sucede nada. Por lo tanto, el primer paso es calcular la profundidad del módulo de giro. Como JavaScript solo sabe cómo calcular el resto, tengo que hacer esto en dos pasos.
  • Un giro de 1mueve el elemento superior al depthelemento. Un giro de 2mueve los dos elementos superiores, etc. Sin embargo, también puede lograr esto moviendo los elementos entre giro y profundidad al frente. spliceelimina esos elementos y los concatantepone a los elementos restantes. (Podría haber utilizado una comprensión de matriz en su lugar, ya que tiene la misma longitud).
  • A diferencia slice, el segundo parámetro splicees el número de elementos que se eliminarán.
Neil
fuente
¿No es lo (t%d+d)%dmismo que t%d?
Lucas
@Luke No, %es el resto, por lo que da una respuesta negativa cuando tes negativa.
Neil
Puede guardar 2 bytes si lo usa, (t,d,...a)=>ya que las reglas permiten que la entrada se pase en un elemento a la vez.
Shaggy
@ Shaggy Gracias, no me había dado cuenta de eso.
Neil
7

CJam, 31 bytes

)\):N@\,0a|={NW*1$1$>)\+@@<\+}*

La entrada y la salida son matrices en la pila, con el último elemento representando la parte superior de la pila.

Seguimiento de pila:

                   e# Stack:                [6 5 4 3 2 1 4 2]
)                  e# Take out first value: [6 5 4 3 2 1 4] 2
\                  e# Swap:                 2 [6 5 4 3 2 1 4]
)                  e# Take out first value: 2 [6 5 4 3 2 1] 4
:N                 e# Store in N:           2 [6 5 4 3 2 1] 4; N=4
@                  e# Rotate:               [6 5 4 3 2 1] 4 2
\                  e# Swap:                 [6 5 4 3 2 1] 2 4
,                  e# Range:                [6 5 4 3 2 1] 2 [0 1 2 3]
0                  e# Push 0:               [6 5 4 3 2 1] 2 [0 1 2 3] 0
a                  e# Wrap in array:        [6 5 4 3 2 1] 2 [0 1 2 3] [0]
|                  e# Logical or:           [6 5 4 3 2 1] 2 [0 1 2 3]
                   e# (This will replace an empty array with [0] to handle a special case of n=0)
=                  e# Get array value:      [6 5 4 3 2 1] 2
{NW*1$1$>)\+@@<\+} e# Push block:           [6 5 4 3 2 1] 2 {NW*1$1$>)\+@@<\+}
*                  e# Preform n times:      [6 5 4 3 2 1]
  N                e# Push N:               [6 5 4 3 2 1] 4
  W*               e# Negate:               [6 5 4 3 2 1] -4
  1$               e# Copy element 1 back:  [6 5 4 3 2 1] -4 [6 5 4 3 2 1]
  1$               e# Copy element 1 back:  [6 5 4 3 2 1] -4 [6 5 4 3 2 1] -4
  >                e# Slice a[-4:]          [6 5 4 3 2 1] -4 [4 3 2 1]
  )                e# Take first value:     [6 5 4 3 2 1] -4 [4 3 2] 1
  \                e# Swap:                 [6 5 4 3 2 1] -4 1 [4 3 2]
  +                e# Append:               [6 5 4 3 2 1] -4 [1 4 3 2]
  @@               e# Rotate twice:         [1 4 3 2] [6 5 4 3 2 1] -4
  <                e# Slice a[:-4]:         [1 4 3 2] [6 5]
  \                e# Swap:                 [6 5] [1 4 3 2]
  +                e# Append:               [6 5 1 4 3 2]
e# Preform the block again:                 [6 5 2 1 4 3]
Fruta Esolanging
fuente
6

Mathematica, 58 50 bytes

Editar: Gracias a Martin Ender por guardar 8 bytes.

Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&@@#&

Explicación:

Función pura que espera una lista donde el comienzo de la lista representa la parte superior de la pila. Pasamos los elementos de la lista a la función pura Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&. xse establece en la secuencia de elementos que comienza con el tercer argumento., luego rotamos los primeros elementos #2(segundo argumento) xhacia la izquierda #(primer argumento) veces, luego Joinlos elementos restantes de x.

Ahorraría 3bytes si solo pasáramos los elementos de la pila como argumentos a la función directamente en lugar de estar en una lista inicialmente, pero luego los formatos de entrada y salida no coincidirían.

Solución original:

#/.{t_,d_,x___}:>{x}~Take~d~RotateLeft~t~Join~Drop[{x},d]&

Hay algo realmente satisfactorio en esta cadena de funciones infijadas. Reemplaza una lista con el primer elemento t, el segundo elemento dy los elementos restantes xcon el resultado de rotar los primeros delementos {x}a los ttiempos de la izquierda y unir los elementos restantes de {x}.

ngenisis
fuente
1
¡Agradable! Puede guardar 3 bytes utilizando una función de prefijo ±de un byte insetad de una regla de reemplazo, y otro 1 byte explotando de la TakeDropsiguiente manera: ±{t_,d_,x___}:=#~RotateLeft~t~Join~#2&@@{x}~TakeDrop~d
Greg Martin
Solo iba a comentar lo mismo que Greg, pero en realidad puedes ir aún más corto. Realice una función variada sin nombre (aunque eso es un poco dudoso porque requiere entrada ...&[1, 1, 3, 4]y devolución {3, 4}o haga eso manualmente con un Applyal principio: Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&@@#&(para ser claros, mi primera sugerencia omite el @@#&.)
Martin Ender
5

Rubí, 40 bytes.

x=->s{n,d,*s=s;s[0,d]=s[0,d].rotate n;s}

Pruébalo en línea!

Toma la entrada como una lista, devuelve una lista. El hecho de que rotateexista un dispositivo incorporado que pueda manejar rotaciones positivas y negativas hace que esto sea trivial.

Ventero
fuente
5

Python, 141 98 87 74 bytes

11 bytes guardados gracias a @Cole

def f(s):*s,d,t=s;n=len(s)-d;return s*0**d or s[:n]+s[-t%d-d:]+s[n:-t%d-d]

Recibe la entrada como una lista, donde el último elemento es la parte superior de la pila.

Utiliza el truco 0ⁿ para filtrar la profundidad cero y el operador de módulo de ajuste de signos de Python para determinar la parte de la lista que se va a cortar.

Uriel
fuente
¿Por qué no solo tomar f(s,t,d)?
cole
@Cole ¡Gracias por desempacar! Sin embargo, no puedo ver a qué se refería con f(s,t,d)(la entrada es la pila completa).
Uriel
idea increíble para desempacar, aunque no creo que debas darme crédito por eso (estaba sugiriendo tomar las variables por separado). La especificación de entrada parece permitirle tomar la profundidad y los giros como variables separadas de la pila: "La entrada y la salida pueden estar en una lista, matriz, cadena con un delimitador, pasado en un elemento a la vez, o en cualquier otro formato razonable. La salida debe estar en el mismo formato que la entrada ".
cole
Puede guardar 1 byte con r=-t%d-d. Además, la sustitución s*0**dcon el s*(d<1)recuento de bytes mantiene, pero tal vez mejora la legibilidad (no es que ese sea el objetivo). Sin embargo, no sabía eso 0**0==1en Python, eso es interesante.
Ben Frankel
@BenFrankel no puedo guardar -t%d-dcomo un valor (como antes), porque cuando destá 0presente desencadenaría una excepción de división por cero.
Uriel
3

JavaScript ES6, 109 92 bytes

x=>{for(i=x.shift(),i=i>0?i:-i,j=x.shift();i-->0&&j>0;)x=x.splice(j,1).concat(x);return x}

Pruébalo en línea!

Recibe entradas en forma de una matriz de enteros.
También tiene el recuento de flecha: P

Explicación:

El código usa la función shift para extraer los dos primeros elementos de la lista.

Luego obtiene el valor absoluto del primer elemento, que es el número de vueltas.

Dado que Javascript está indexado a cero, el índice de profundidad debe reducirse en 1.

Si el índice de profundidad fuera 0 o 1, nada debería cambiar, pero debido a la disminución, el índice de 0 causaría cambios. Por lo tanto, salga del bucle si el índice de profundidad no es <= 0.

La función de empalme (a, b) devuelve el subconjunto de longitud b con el índice inicial a del conjunto y deja el conjunto original sin esos elementos.

Cuando se concatena con el resto de la matriz original, esta es una rotación única de la matriz en el índice de profundidad.

Al realizar esta operación n veces, donde n es el número de vueltas, la matriz resultante es el resultado del operador de balanceo.

fəˈnɛtɪk
fuente
2

TI-Basic, 141 150 bytes (sin competencia)

Prompt L1
L1(1→T
L1(2→D
seq(L1(C),C,3,dim(L1→L1
If TD>0
Then
For(A,1,T
L1(1→B
For(C,2,D
L1(C→L1(C–1
End
B→L1(D
End
End
If TD<0
Then
For(A,1,-T
L1(D→B
For(C,D,2,-1
L1(C–1→L1(C
End
B→L1(1
End
End
L1

Edición: caso fijo donde la profundidad es cero (+9 bytes)

TI-Basic no admite listas de longitud 0, por lo que este enfoque no funcionará para una entrada de dos longitudes.

Explicación:

Prompt L1                # 4 bytes, input list
L1(1→T                   # 7 bytes, turns
L1(2→D                   # 7 bytes, depth
seq(L1(C),C,3,dim(L1→L1   # 18 bytes, remove turns and depth from list
If TD>0                  # 6 bytes, if turns is positive and depth is nonzero (can't be negative)
Then                     # 2 bytes
For(A,1,T                # 7 bytes, do this 'turns' times
L1(1→B                    # 7 bytes, backup the first item
For(C,2,D                # 7 bytes, shuffle the rest along
L1(C→L1(C–1               # 12 bytes
End                      # 2 bytes
B→L1(D                   # 7 bytes, restore the backup to where it should be
End                      # 2 bytes
End                      # 2 bytes
If TD<0                  # 6 bytes, if T is negative and D is nonzero
Then                     # 2 bytes
For(A,1,-T               # 8 bytes, do this -'turns' times
L1(D→B                   # 7 bytes, backup the Dth item
For(C,D,2,-1             # 10 bytes, shuffle the items the other way
L1(C–1→L1(C              # 12 bytes
End                      # 2 bytes
B→L1(1                   # 7 bytes, restore backup to where it belongs
End                      # 2 bytes
End                      # 2 bytes
L1                       # 2 bytes, implicitly return
pizzapants184
fuente
Creo que también necesita código para lidiar con el caso de la lista de 2 elementos; actualmente se producirá un error en el seq(.
lirtosiast el
1

Lote, 163 bytes

@set s=
@set r=
@set/ad=%2,t=(%1%%d+d)%%d
:l
@shift
@set/af=t-=1,f^^=d-=1
@if %f% lss 0 (set r=%r% %2)else set s=%s% %2
@if not "%3"=="" goto l
@echo%r%%s%

Toma la entrada como parámetros de línea de comandos y genera una lista separada por espacios. Los parámetros entre ty dse extraen en la rvariable para que puedan anteponerse a la svariable, que recibe todos los demás parámetros.

Neil
fuente