Sekwencja skorupy Koopa

19

W różnych grach Super Mario zielone i czerwone pociski Koopa Troopa mogą ślizgać się bez tarcia na płaskich powierzchniach i niszczyć ceglane bloki na ich drodze. Kiedy pocisk uderza w klocek, blok pęka, zamieniając go w pustą przestrzeń, a pocisk Koopa zmienia kierunek. Jako przykład obejrzyj tutaj czerwoną powłokę .

Załóżmy, że poziom Super Mario ma tylko jeden blok wysokości, a każda komórka siatki jest cegłą lub pustym miejscem, z wyjątkiem lewej komórki, która zawiera poruszającą się w prawo powłokę. Poziom jest również okresowy , więc jeśli pocisk wyjdzie z prawej lub lewej krawędzi poziomu, ponownie pojawi się po przeciwnej stronie. W tej sytuacji pocisk będzie się odbijał i łamał wszystkie cegiełki na poziomie, dopóki nie będzie ich więcej. Jak daleko posunie się pocisk tuż po zerwaniu ostatniego bloku z cegły?

Wyzwanie

Napisz program lub funkcję, która przyjmuje nieujemną liczbę całkowitą dziesiętną. Liczba ta, wyrażona w postaci binarnej bez zer wiodących (jedynym wyjątkiem jest sama 0), koduje układ na poziomie jednego bloku. A 1to blok z cegły, a a 0to pusta przestrzeń.

Powłoka Koopa jest wstawiana na bardzo lewej krawędzi poziomu i początkowo porusza się w prawo. Na przykład poziom związany z danymi wejściowymi 39to

>100111

ponieważ 100111jest 39 w systemie binarnym >i <reprezentuje odpowiednio prawą i lewą ruchomą powłokę.

Musisz wydrukować lub zwrócić całkowitą odległość przebytą przez pocisk po 1zerwaniu ostatniego bloku cegły (aka ).

Dane wyjściowe dla 39to 7i zmiany w poziomie wyglądają następująco:

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

Podobnie, sygnał wyjściowy dla 6Is 1:

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

Najkrótszy kod w bajtach wygrywa.

Dla odniesienia, oto dane wyjściowe dla danych wejściowych 0do 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

A oto wyjścia do wejścia 1000.

Hobby Calvina
źródło

Odpowiedzi:

6

CJam, 29 26 24 bajtów

Dzięki Sp3000 za oszczędność 3 bajtów.

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

Zestaw testowy. (Spowoduje to wydrukowanie wszystkich wyników od 0 do liczby całkowitej podanej na STDIN.)

Wyjaśnienie

To trochę odwraca specyfikację na głowie: zamiast przesuwać powłokę przez ciąg binarny, przesuwamy i odwracamy ciąg binarny, tak aby skorupa zawsze znajdowała się z przodu, wskazując w prawo:

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
źródło
5

Pyth, 24 bajty

&.WsH_XZeaYxZ1 0jQ2ssPBY

Wypróbuj online: pakiet demonstracyjny lub testowy

Poniższy 22 bajtowy kod powinien również załatwić sprawę. Obecnie nie działa z powodu błędu w kompilatorze Pyth.

&u_XGeaYxG1ZjQ2)ssPBPY

edycja: Naprawiono błąd, ale oczywiście rozwiązanie się nie liczy.

Wypróbuj online: pakiet demonstracyjny lub testowy

Wyjaśnienie:

Na przemian z przodu iz tyłu wykonuję następujące czynności:

  • Szukam 1
  • Zapamiętaj ten indeks, umieszczając go na liście
  • Zaktualizuj 1 do 0

Gdy nie ma już 1, obliczam odległość. Ważne jest: Powłoka przesuwa się dwukrotnie na każdą odległość na liście (do przodu i do tyłu), z wyjątkiem ostatniej odległości.

&.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
źródło