É assim que nós fazemos


18

Piet é uma linguagem de programação interessante por várias razões. Hoje vamos nos concentrar em um motivo: o comando roll . O comando roll foi originalmente do PostScript e é uma maneira poderosa de manipular a pilha.

O comando roll exibe os dois principais elementos da pilha e os utiliza como parâmetros. Vamos chamar o primeiro valor popped turnse o segundo depth. Uma volta para a profundidade n pega o elemento mais alto da pilha, torna-o o enésimo elemento na pilha e move cada um dos elementos acima dela para cima um. Se turns for negativo, isso é feito na direção oposta. Ou seja, o enésimo elemento é movido para o topo e os outros elementos são movidos para baixo. Isso é repetido abs(turns)vezes.

Desafio

Escreva um programa ou função que pegue uma pilha e retorne essa pilha depois de executar um rolo.

Regras

  • A entrada e a saída podem estar em uma lista, matriz, sequência com um delimitador, transmitidos em um elemento por vez ou em qualquer outro formato razoável. A saída deve estar no mesmo formato que a entrada.
  • depth nunca será negativo e nunca será maior que o comprimento da pilha.
  • A pilha de entrada sempre conterá pelo menos dois elementos.
  • Isso é então a resposta mais curta em cada idioma vence. Como tal, não aceitarei uma resposta.
  • As brechas padrão são proibidas.

Casos de teste

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

2
resposta mais curta em cada idioma ganha , não é assim que o [code-golf] funciona. A resposta mais curta vence. Período.
mbomb007

4
@ mbomb007 ahem e quanto a isso
Christopher

7
Fiquei muito desapontado por isso não envolver Rick Rolling
Christopher

2
@ mbomb007 Não vejo isso na descrição da tag ou em uma pesquisa rápida na meta, então não acho que seja esse o caso.
Mike Bufardeci

2
@ mbomb007 Se você quiser que eu mude, por favor, forneça algum tipo de argumento além de dizer "você está errado e eu estou certo" repetidamente. Há um precedente para isso, que você rejeitou e em nenhum lugar diz que os desafios exigem exatamente um vencedor ou que uma resposta deve ser aceita.
Mike Bufardeci

Respostas:


8

Haskell , 64 62 bytes

Edit: -2 bytes: @xnor viu algo que eu pensava errado.

rpega e retorna uma lista de Ints.

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

Experimente online!

splitAt n ldivide uma lista lno índice n, modcalcula o restante da divisão, ++concatena as listas.


1
Eu acho que você pode cortar 2 bytes, definindo (%)=splitAtinfix.
Xnor

@xnor Oh, eu tinha de alguma forma me convenci de que não iria funcionar
Ørjan Johansen

8

JavaScript (ES6), 49 47 bytes

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

Editar: salvou 2 bytes graças ao @Shaggy, tomando os elementos da pilha como parâmetros separados. Explicação:

  • Quando o turno é múltiplo da profundidade, nada acontece. O primeiro passo é, portanto, calcular a profundidade do módulo de curva. Como o JavaScript sabe apenas como calcular o restante, tenho que fazer isso em duas etapas.
  • Uma volta 1move o elemento superior para o depthelemento. Uma volta 2move os dois elementos principais, etc. No entanto, você também pode conseguir isso movendo os elementos entre a volta e a profundidade para a frente. spliceremove esses elementos e os concatanexa aos elementos restantes. (Eu poderia ter usado uma compreensão de matriz, pois tem o mesmo comprimento.)
  • Ao contrário slice, o segundo parâmetro para spliceé o número de elementos a serem removidos.

Não é (t%d+d)%do mesmo que t%d?
Lucas

@ Lucas Não, %é o restante, portanto, dá uma resposta negativa quando té negativa.
314 Neil

Você pode salvar 2 bytes usando (t,d,...a)=>como as regras permitem que a entrada seja passada em um elemento por vez.
Shaggy

@ Shaggy Obrigado, eu não tinha notado isso.
5177 Neil

7

CJam, 31 bytes

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

Entrada e saída são matrizes na pilha, com o último elemento representando a parte superior da pilha.

Rastreio de pilha:

                   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]

6

Mathematica, 58 50 bytes

Edit: Obrigado a Martin Ender por salvar 8 bytes.

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

Explicação:

Função pura que espera uma lista em que o início da lista represente o topo da pilha. Passamos os elementos da lista para a função pura Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&. xé definido como a sequência de elementos começando com o terceiro argumento., em seguida, rotacionamos o primeiro #2(segundo argumento) dos elementos xpara os #tempos à esquerda (primeiro argumento) e, em seguida, Joinos elementos restantes dex .

Economizaria 3 bytes se apenas passássemos os elementos da pilha como argumentos para a função diretamente, em vez de estarmos em uma lista inicialmente, mas os formatos de entrada e saída não coincidiriam.

Solução original:

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

Há algo realmente satisfatório nessa cadeia de funções infix. Substitui uma lista pelo primeiro elemento t, segundo elemento de elementos restantes xpelo resultado de girar os primeiros delementos {x}para os ttempos esquerdos e unir os elementos restantes de {x}.


1
Agradável! Você pode salvar 3 bytes usando um one-byte função prefixo ±insetad de uma regra de substituição, e outro 1 byte, explorando TakeDropos seguintes: ±{t_,d_,x___}:=#~RotateLeft~t~Join~#2&@@{x}~TakeDrop~d
Greg Martin

Eu ia comentar a mesma coisa que Greg, mas você pode ir ainda mais curto. Quer fazer uma função de aridade variável sem nome (apesar de que é um pouco desertor porque leva de entrada ...&[1, 1, 3, 4]e retorno {3, 4}ou fazer isso manualmente com um Applyno início: Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&@@#&(só para ficar claro, a minha primeira sugestão omite a @@#&).
Martin Ender

5

Ruby, 40 bytes

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

Experimente online!

Pega a entrada como uma lista, retorna uma lista. O fato de rotateexistir um built-in que pode lidar com rotações positivas e negativas torna isso trivial.


5

Python, 141 98 87 74 bytes

11 bytes salvos graças ao @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]

Recebe entrada como uma lista, onde o último elemento é o topo da pilha.

Usa o truque 0ⁿ para filtrar a profundidade zero e o operador de módulo de ajuste de sinal do python para determinar a parte da lista a ser cortada.


Por que não apenas pegar f(s,t,d)?
Cole

@ Obrigado Obrigado pela descompactação! No entanto, não consigo ver o que você quis dizer com f(s,t,d)(entrada é a pilha inteira).
Uriel

ótima idéia para descompactar, embora eu não ache que você deva me creditar por isso (eu estava sugerindo apenas levar as variáveis ​​separadamente). A especificação de entrada parece permitir que você analise a profundidade e as voltas como variáveis ​​separadas da pilha: "A entrada e a saída podem estar em uma lista, matriz, string com um delimitador, transmitidas em um elemento por vez ou em qualquer outro formato razoável. A saída deve estar no mesmo formato que a entrada ".
Cole

Você pode economizar 1 byte com r=-t%d-d. Além disso, a substituição s*0**dpor s*(d<1)mantém a contagem de bytes, mas talvez melhore a legibilidade (não é esse o objetivo). Eu não sabia que, 0**0==1em Python, isso é interessante.
Ben Frankel

@BenFrankel eu não posso salvar -t%d-dcomo um valor (como eu fiz antes), porque quando dé 0isso iria desencadear uma exceção de divisão por zero.
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}

Experimente online!

Recebe entrada na forma de uma matriz de números inteiros.
Também tem a contagem para a seta: P

Explicação:

O código usa a função shift para extrair os dois primeiros elementos da lista.

Ele então obtém o valor absoluto do primeiro elemento, que é o número de voltas.

Como o Javascript é zero indexado, o índice de profundidade precisa ser diminuído em 1.

Se o índice de profundidade for 0 ou 1, nada deve mudar, mas, devido à diminuição, o índice de 0 causaria alterações. Portanto, saia do loop se o índice de profundidade não for <= 0.

A função de emenda (a, b) retorna a sub-matriz de comprimento b com o índice inicial a da matriz e deixa a matriz original sem esses elementos.

Quando concatenada com o restante da matriz original, essa é uma rotação única da matriz no índice de profundidade.

Executando essa operação n vezes, em que n é o número de voltas, a matriz resultante é o resultado do operador de rolagem.



2

TI-Basic, 141 150 bytes (não competitivo)

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

Editar: caso fixo em que a profundidade é zero (+9 bytes)

O TI-Basic não suporta listas de tamanho 0, portanto, essa abordagem não funcionará para uma entrada de dois tamanhos.

Explicação:

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

Eu acho que você precisa de código para lidar com o caso de lista de 2 elementos também; Atualmente, ele irá erro no seq(.
precisa saber é o seguinte

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%

Recebe a entrada como parâmetros da linha de comando e gera uma lista separada por espaços. Os parâmetros entre te dsão extraídos na rvariável para que possam ser anexados à svariável, que recebe todos os outros parâmetros.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.