Tumpukan dek!

15

Alice dan Bob suka memainkan permainan kartu, dengan setumpuk kartu bernomor dengan bilangan bulat non-negatif berturut-turut.

Alice memiliki cara yang sangat khusus untuk mengocok dek. Pertama, dia mengambil kartu paling atas dari geladak dan meletakkannya di bagian bawah geladak. Lalu dia mengeluarkan kartu berikutnya, dan mulai tumpukan dengan itu. Kemudian, lagi-lagi dia memutar kartu teratas ke bawah, dan meletakkan kartu teratas baru ke tumpukan. Dia mengulangi proses ini sampai dia mengosongkan dek, di mana titik tumpukan adalah dek baru.

  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 | 

Gambar 1: Alice melakukan shuffle-nya di dek 5-kartu "3, 1, 4, 0, 2". Bagian belakang kartu semuanya menghadap ke kiri.

Suatu hari, Bob mengumumkan dia akan berlibur selama seminggu. Alice, yang tidak memiliki siapa pun untuk bermain game, mendaftarkan temannya Eve. Sekarang, Eve adalah penipu yang tak tahu malu, jadi ketika dia melihat pengocokan aneh Alice, dia menyadari bahwa dia bisa menumpuk dek sebelumnya untuk keuntungannya!

Ketika Eve pulang setelah hari pertama, dia melakukan beberapa analisis pada permainan dan menemukan bahwa peluang terbaiknya adalah ketika kartu berada di urutan 0, 1, 2, 3, 4, 5, ... Dia tidak menangkap berapa banyak kartu yang ada di geladak, jadi dia menetas skema yang tidak jelas untuk menulis beberapa kode di lengannya yang, ketika dijalankan, mengambil ukuran geladak dan menampilkan urutan yang diperlukan Hawa untuk memasukkan kartunya, sehingga ketika Alice mengocok dek, dek terakhir ada di urutan 0, 1, 2, 3, ...

Hawa tidak peduli apa bahasa kode itu (dia tahu semuanya), atau apakah kode tersebut adalah fungsi yang mengambil argumen integer dan mengembalikan array, atau program penuh mengambil input melalui argumen baris perintah atau STDIN dan menulis hasilnya ke STDOUT. Namun, dia membutuhkan kode sesingkat mungkin, untuk memperkecil kemungkinan Alice melihatnya dan menangkapnya.

Tidak bermoral, bisakah kalian membantu Hawa?

Contoh input dan output:

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
algoritme hiu
sumber
3
Ungkapan yang indah, saya akan mendapatkan retak.
21ıʇǝɥʇu
Agak membingungkan bahwa tumpukan Anda disejajarkan di atas. Dan menyatakan urutan tumpukan secara eksplisit juga akan membantu memperjelas pertanyaannya.
Martin Ender
Hal yang sama berlaku untuk geladak.
Martin Ender
Juga: apakah Anda mencoba menipu kami dengan memiliki sampel dengan panjang 5? Tanpa ingin rampasan: shuffle(shuffle(range(5))) == range(5)...
ɐɔıʇǝɥʇuʎs
@ Sintetica Saya kira itu kebetulan bahwa pengocokan Alice pada kartu 5-kartu adalah involusi. Saya tidak benar-benar memikirkannya ketika memposting karena itu tidak berlaku secara umum.
algorithmshark

Jawaban:

5

GolfScript, 15 14 13 byte

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

Cobalah online.

Contoh

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

Bagaimana itu bekerja

])    # 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
sumber
1
Anda mungkin menggunakan {}/alih-alih operator peta untuk menyimpan char.
Howard
Terima kasih! Saya ingin sebuah array, jadi saya menggunakan peta. Kekuatan kebiasaan ...
Dennis
1
](karena dua karakter pertama secara efektif menempatkan array kosong di bawah input, menghemat Anda nanti []\ .
Peter Taylor
Terima kasih! Butuh waktu terlalu lama bagi saya untuk mencari tahu mengapa ini tidak bekerja dengan penerjemah online. Lupa menghapus tumpukan ...
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)

Elemen terakhir dalam vektor yang dikembalikan adalah bagian atas dek.

gggg
sumber
4

Mathematica, 92 77 46 byte

Mengharapkan input dalam variabel n:

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

Ini hanya memutar acak mundur, dengan memindahkan kartu dan kemudian meletakkan kartu bagian bawah di atas.

EDIT: Tidak perlu melacak tumpukan output, cukup iterate melalui integer.

Martin Ender
sumber
2

Python 2.7 - 57

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

Bagus dan sederhana, balikkan shuffle. Cukup dekat dengan bagaimana Golfscript melakukannya.

isaacg
sumber
1

J (13 karakter) dan K (9)

Ternyata, ini adalah proses sederhana untuk membatalkan pengocokan, dan APL-suka memiliki kata keterangan lipat /untuk membantu mereka membuat ini sesingkat mungkin.

J mengambil 13 char dengan (_1|.,)/@i.@-, sedangkan K hanya membutuhkan 9: |(1!,)/!:. APL juga akan sama singkatnya.

Inilah jejak langkah demi langkah dari versi 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

Anda mungkin melihat bahwa di J, kita membalikkan array bilangan bulat pertama, tapi di K kita lakukan setelah itu: ini adalah karena K lipat lebih seperti foldl, dibandingkan dengan J foldr.

algoritme hiu
sumber