Urutan Shell Koopa

19

Dalam berbagai game Super Mario, kerang Koopa Troopa hijau dan merah dapat meluncur tanpa gesekan pada permukaan datar dan menghancurkan balok bata yang menghalangi mereka. Ketika sebuah shell menabrak blok bata, blok itu pecah, mengubahnya menjadi ruang kosong, dan shell Koopa berbalik arah. Sebagai contoh, perhatikan cangkang merah di sini .

Misalkan tingkat Super Mario hanya satu blok tinggi dan setiap sel kotak baik batu bata atau ruang kosong, kecuali sel paling kiri yang berisi cangkang yang bergerak ke kanan. Levelnya juga periodik , jadi jika shell keluar dari tepi kanan atau kiri level itu akan masuk kembali di sisi yang berlawanan. Dalam situasi ini cangkang akan terus memantul dan memecah semua balok bata di tingkat sampai tidak ada lagi. Seberapa jauh shell akan melakukan perjalanan tepat setelah blok bata terakhir rusak?

Tantangan

Tulis program atau fungsi yang menggunakan bilangan desimal non-negatif. Angka ini, dinyatakan dalam biner tanpa nol di depan (satu-satunya pengecualian adalah 0 itu sendiri), mengkodekan tata letak tingkat tinggi satu blok. A 1adalah balok bata dan 0ruang kosong.

Shell Koopa dimasukkan di tepi paling kiri tingkat dan awalnya bergerak ke kanan. Misalnya, level yang terkait dengan input 39adalah

>100111

karena 10011139 dalam biner, dan >dan <masing-masing mewakili cangkang bergerak kanan dan kiri.

Anda perlu mencetak atau mengembalikan jarak total yang ditempuh oleh shell setelah blok bata terakhir (alias 1) telah rusak.

Output untuk 39is 7dan perubahan pada level terlihat seperti ini:

Level      Cumulative Distance
>100111    0
<000111    0
>000110    0
0>00110    1
00>0110    2
000>110    3
000<010    3
00<0010    4
0<00010    5
<000010    6
000001<    7
000000>    7  <-- output

Demikian pula, output untuk 6adalah 1:

Level    Cumulative Distance
>110     0
<010     0
001<     1
000>     1  <-- output

Kode terpendek dalam byte menang.

Untuk referensi, berikut adalah output untuk input 0ke 20:

0 0
1 0
2 0
3 0
4 0
5 0
6 1
7 1
8 0
9 0
10 1
11 2
12 2
13 1
14 3
15 3
16 0
17 0
18 1
19 3
20 2

Dan di sini adalah output hingga input 1000.

Hobi Calvin
sumber

Jawaban:

6

CJam, 29 26 24 byte

Terima kasih kepada Sp3000 untuk menghemat 3 byte.

q~2b{_1&}{W\({%}*0+}w],(

Suite uji. (Ini mencetak semua hasil dari 0 hingga bilangan bulat yang diberikan pada STDIN.)

Penjelasan

Ini memutar spec pada kepalanya sedikit: alih-alih menggerakkan shell melalui string biner, kami menggeser dan membalikkan string biner sedemikian rupa sehingga shell selalu di depan, menunjuk ke kanan:

q~      e# Read and evaluate the input.
2b      e# Convert to base-2 to get the "level".
{_1&}{  e# While there is a 1 in the level...
  W\    e#   Put a -1 below the level.
  (     e#   Pull off the first digit, i.e. the cell the shell is pointing at.
  {     e#   If it's a 1 (i.e. a brick)...
    %   e#     Reverse the level, consuming the -1. This isequivalent to reversing the 
        e#     shell in place.
  }*
  0+    e#   Append a zero. If the cell was a brick, this just replaces it with an empty
        e#   cell. Otherwise, this rotates the level by one cell. This is equivalent 
        e#   to moving the shell one cell through the periodic level.
        e#   Note that if the leading cell was 0, the -1 remains on the stack.
}w
],(     e# Wrap the stack in an array, get its length and decrement.
Martin Ender
sumber
5

Pyth, 24 byte

&.WsH_XZeaYxZ1 0jQ2ssPBY

Cobalah online: Demonstrasi atau Test Suite

Kode 22 byte berikut juga harus melakukan trik. Saat ini tidak berfungsi, karena bug di kompiler Pyth.

&u_XGeaYxG1ZjQ2)ssPBPY

sunting: Bug diperbaiki, tetapi tentu saja solusinya tidak masuk hitungan.

Cobalah online: Demonstrasi atau Test Suite

Penjelasan:

Bergantian dari depan dan belakang saya lakukan hal berikut:

  • Saya mencari 1
  • Ingat indeks ini dengan memasukkannya ke dalam daftar
  • Perbarui 1 ini hingga 0

Ketika tidak ada 1 yang tersisa, saya menghitung jarak. Penting adalah: Shell bergerak setiap jarak dalam daftar dua kali (maju dan mundur), kecuali jarak terakhir.

&.WsH_XZeaYxZ1 0jQ2ssPBY   implicit: Y = empty list
                jQ2        convert input number to binary
 .WsH                      start with Z=^; 
                           while the sum(Z) > 0, apply the the following to Z:
           xZ1                index of 1 in Z
         aY                   append this to Y
        e                     take the last element of Y (=this index)
      XZ       0              set this 1 (at index ^) in Z to 0
     _                        and revert the order of Z
                           this returns a list of zeros
&                          don't print ^, print the next thing
                     PBY   creates the list [Y, Y[:-1]]
                    s      combine these lists
                   s       sum up the distances
Jakube
sumber