Empilhe o baralho!

15

Alice e Bob gostam de jogar um jogo de cartas, com um baralho numerado com números inteiros não negativos consecutivos.

Alice tem uma maneira muito particular de embaralhar o convés, no entanto. Primeiro, ela pega a carta do topo do baralho e a coloca no fundo do baralho. Então ela remove a próxima carta e começa uma pilha com ela. Então, novamente, ela muda a carta do topo para o fundo e coloca a nova carta do topo na pilha. Ela repete esse processo até esvaziar o baralho, quando a pilha é o novo baralho.

  deck     |  pile
-----------+-----------
 3 1 4 0 2 | 
 1 4 0 2 3 | 
 4 0 2 3   |         1
 0 2 3 4   |         1
 2 3 4     |       0 1
 3 4 2     |       0 1
 4 2       |     3 0 1
 2 4       |     3 0 1
 4         |   2 3 0 1
           | 4 2 3 0 1
 4 2 3 0 1 | 

Figura 1: Alice realiza seu embaralhamento no baralho de 5 cartas "3, 1, 4, 0, 2". As costas das cartas estão todas voltadas para a esquerda.

Um dia, Bob anuncia que está tirando férias de uma semana. Alice, não tendo ninguém para jogar, convoca sua amiga Eve. Agora, Eve é uma trapaceira desavergonhada, então quando ela vê o embaralhamento peculiar de Alice, ela percebe que pode empilhar o baralho de antemão para sua vantagem!

Quando Eve chega em casa após o primeiro dia, ela faz algumas análises sobre o jogo e descobre que suas melhores chances são quando as cartas estão na ordem de 0, 1, 2, 3, 4, 5, ... Ela não o fez. No entanto, ela pega quantas cartas havia no baralho, então ela traça um esquema estanque para escrever um código em seu braço que, quando executado, pega o tamanho do baralho e exibe a ordem em que Eve precisa colocar as cartas, para que quando Alice embaralha o baralho, o baralho final está na ordem 0, 1, 2, 3, ...

Para Eve, não importa realmente em que idioma está o código (ela conhece todos), ou se o código é uma função que usa um argumento inteiro e retorna uma matriz ou um programa completo que recebe entradas por meio de um argumento de linha de comando ou STDIN e escrevendo os resultados para STDOUT. Ela, no entanto, precisa do código o mais curto possível, para minimizar a chance de Alice vê-lo e pegá-lo.

Por mais imoral que possa ser, vocês podem ajudar Eve?

Exemplos de entradas e saídas:

in  out
 1  0
 2  0 1
 5  2 4 0 3 1
10  2 9 4 8 0 7 3 6 1 5
52  6 51 25 50 12 49 24 48 1 47 23 46 11 45 22 44 5 43 21 42 10 41 20 40 2 39 19
    38 9 37 18 36 4 35 17 34 8 33 16 32 0 31 15 30 7 29 14 28 3 27 13 26
algoritmshark
fonte
3
Lindo fraseado, eu vou rachar.
ɐɔıʇǝɥʇuʎs
É um pouco confuso que suas pilhas estejam alinhadas na parte superior. E declarar a ordem da pilha explicitamente também ajudaria a esclarecer um pouco a questão.
Martin Ender
O mesmo vale para o convés.
Martin Ender
Além disso: você está tentando nos enganar com uma amostra do comprimento 5? Sem querer estragar: shuffle(shuffle(range(5))) == range(5)... #
2121
@ Synthetica Acho que acontece que o baralho de Alice em um baralho de 5 cartas é uma involução. Eu realmente não pensei nisso ao postar, porque geralmente não é válido.
algorithmshark

Respostas:

5

GolfScript, 15 14 13 bytes

])~,{\+)\+}/`

Experimente online.

Exemplo

$ golfscript alice.gs <<< 10
[2 9 4 8 0 7 3 6 1 5]

Como funciona

])    # Collect the stack into an array and pop. This leaves [] below the input string.
~     # Interpret the input string.
,     # For input “N”, push the array [ 0 … N-1 ] (the pile).
{     # For each card on the pile:
  \+  # Put the card on top of the deck.
  )   # Remove a card from the bottom of the deck.
  \+  # Put the card on top of the deck.
}/    #
`     # Convert the deck into a string.
Dennis
fonte
1
Você pode usar em {}/vez do operador de mapa para salvar um caractere.
224 Howard
Obrigado! Eu queria uma matriz, então usei o mapa. Força do hábito ...
Dennis
1
](como os dois primeiros caracteres efetivamente coloca uma matriz vazia sob a entrada, economizando mais tarde []\ .
22414 Peter Taylor em São
Obrigado! Levei muito tempo para descobrir por que isso não estava funcionando com o intérprete online. Esqueceu-se de limpar a pilha ...
Dennis
5

Julia, 83

u(n)=(a=[n-1:-1:0];l=Int[];[push!(l,shift!(push!(l,pop!(a)))) for i=1:length(a)];l)

O último elemento no vetor retornado é o topo do baralho.

gggg
fonte
4

Mathematica, 92 77 46 bytes

Espera a entrada na variável n:

l={};(l=RotateRight[{#-1}~Join~l])&/@Range@n;l

É literalmente jogar o shuffle para trás, movendo-se sobre uma carta e colocando a carta de baixo por cima.

EDITAR: Não há necessidade de acompanhar a pilha de saída, basta percorrer os números inteiros.

Martin Ender
fonte
2

Python 2.7 - 57

d=[0]
for j in range(1,input()):d=[d.pop()]+[j]+d
print d

Bonito e simples, basta inverter o shuffle. Bastante próximo de como o Golfscript faz isso.

isaacg
fonte
1

J (13 caracteres) e K (9)

Como se vê, é um processo simples de desfazer a reprodução aleatória, e os curtidos de APL têm o advérbio fold / para ajudá-los a tornar isso o mais curto possível.

J leva 13 caracteres com (_1|.,)/@i.@-, enquanto K precisa apenas de 9:|(1!,)/!: . O APL seria similarmente conciso.

Aqui está um rastreio passo a passo da versão J.

(_1|.,)/@i.@- 4                  NB. recall that J is right-associative
(_1|.,)/@i. - 4                  NB. u@v y  is  u v y
(_1|.,)/@i. _4                   NB. monad - is Negate
(_1|.,)/ i. _4                   NB. @
(_1|.,)/ 3 2 1 0                 NB. monad i. is Integers, negative arg reverses result
3 (_1|.,) 2 (_1|.,) 1 (_1|.,) 0  NB. u/ A,B,C  is  A u B u C
3 (_1|.,) 2 (_1|.,) _1 |. 1 , 0  NB. x (M f g) y  is  M f x g y
3 (_1|.,) 2 (_1|.,) _1 |. 1 0    NB. dyad , is Append
3 (_1|.,) 2 (_1|.,) 0 1          NB. dyad |. is Rotate
3 (_1|.,) _1 |. 2 , 0 1          NB. repeat ad nauseam
3 (_1|.,) _1 |. 2 0 1
3 (_1|.,) 1 2 0
_1 |. 3 , 1 2 0
_1 |. 3 1 2 0
0 3 1 2

Você pode notar que no J, invertemos a matriz de números inteiros primeiro, mas no K o fazemos depois: isso ocorre porque a dobra K é mais como a foldl, em comparação com os J's foldr.

algoritmshark
fonte