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 turns
e 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 é código-golfe, 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
Respostas:
Haskell ,
6462 bytesEdit: -2 bytes: @xnor viu algo que eu pensava errado.
r
pega e retorna uma lista deInt
s.Experimente online!
splitAt n l
divide uma listal
no índicen
,mod
calcula o restante da divisão,++
concatena as listas.fonte
(%)=splitAt
infix.JavaScript (ES6),
4947 bytesEditar: salvou 2 bytes graças ao @Shaggy, tomando os elementos da pilha como parâmetros separados. Explicação:
1
move o elemento superior para odepth
elemento. Uma volta2
move 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.splice
remove esses elementos e osconcat
anexa aos elementos restantes. (Eu poderia ter usado uma compreensão de matriz, pois tem o mesmo comprimento.)slice
, o segundo parâmetro parasplice
é o número de elementos a serem removidos.fonte
(t%d+d)%d
o mesmo quet%d
?%
é o restante, portanto, dá uma resposta negativa quandot
é negativa.(t,d,...a)=>
como as regras permitem que a entrada seja passada em um elemento por vez.CJam, 31 bytes
Entrada e saída são matrizes na pilha, com o último elemento representando a parte superior da pilha.
Rastreio de pilha:
fonte
Mathematica,
5850 bytesEdit: Obrigado a Martin Ender por salvar 8 bytes.
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 elementosx
para os#
tempos à esquerda (primeiro argumento) e, em seguida,Join
os 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:
Há algo realmente satisfatório nessa cadeia de funções infix. Substitui uma lista pelo primeiro elemento
t
, segundo elementod
e elementos restantesx
pelo resultado de girar os primeirosd
elementos{x}
para ost
tempos esquerdos e unir os elementos restantes de{x}
.fonte
±
insetad de uma regra de substituição, e outro 1 byte, explorandoTakeDrop
os seguintes:±{t_,d_,x___}:=#~RotateLeft~t~Join~#2&@@{x}~TakeDrop~d
...&[1, 1, 3, 4]
e retorno{3, 4}
ou fazer isso manualmente com umApply
no início:Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&@@#&
(só para ficar claro, a minha primeira sugestão omite a@@#&
).Ruby, 40 bytes
Experimente online!
Pega a entrada como uma lista, retorna uma lista. O fato de
rotate
existir um built-in que pode lidar com rotações positivas e negativas torna isso trivial.fonte
Python,
141988774 bytes11 bytes salvos graças ao @Cole
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.
fonte
f(s,t,d)
?f(s,t,d)
(entrada é a pilha inteira).r=-t%d-d
. Além disso, a substituiçãos*0**d
pors*(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==1
em Python, isso é interessante.-t%d-d
como um valor (como eu fiz antes), porque quandod
é0
isso iria desencadear uma exceção de divisão por zero.JavaScript ES6,
10992 bytesExperimente 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.
fonte
Python 2 , 48 bytes
Experimente online!
fonte
TI-Basic,
141150 bytes (não competitivo)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:
fonte
seq(
.Lote, 163 bytes
Recebe a entrada como parâmetros da linha de comando e gera uma lista separada por espaços. Os parâmetros entre
t
ed
são extraídos nar
variável para que possam ser anexados às
variável, que recebe todos os outros parâmetros.fonte