Koopa-Shell-Sequenz

19

In verschiedenen Super Mario Spiele grün und rot Koopa Schalen können reibungsfrei auf flachen Oberflächen gleiten und zerstören Ziegelsteinblöcke , die in ihrer Art sind. Wenn eine Muschel auf einen Ziegelsteinblock trifft, bricht der Block und verwandelt ihn in einen leeren Raum. Die Koopa-Muschel kehrt die Richtung um. Sehen Sie sich hier als Beispiel die rote Muschel an .

Angenommen, ein Super Mario-Level ist nur einen Block hoch und jede Gitterzelle ist entweder ein Ziegelstein oder ein leerer Bereich, mit Ausnahme der Zelle ganz links, die eine sich nach rechts bewegende Hülle enthält. Die Ebene ist ebenfalls periodisch . Wenn die Shell den rechten oder linken Rand der Ebene verlässt, tritt sie auf der gegenüberliegenden Seite wieder ein. In dieser Situation prallt die Schale weiter ab und zerbricht alle Ziegelblöcke im Level, bis keine mehr vorhanden sind. Wie weit ist die Granate gereist, nachdem der letzte Ziegelstein gebrochen wurde?

Herausforderung

Schreiben Sie ein Programm oder eine Funktion, die eine nicht negative Dezimalzahl akzeptiert. Diese Zahl, die in Binärform ohne führende Nullen ausgedrückt wird (die einzige Ausnahme ist 0 selbst), codiert das Ein-Block-High-Level-Layout. A 1ist ein Ziegelsteinblock und a 0ist ein leerer Raum.

Die Koopa-Muschel wird ganz links im Level eingefügt und bewegt sich zunächst nach rechts. Zum Beispiel kann der Pegel mit dem Eingang zugeordnet 39ist ,

>100111

weil 10011139 in binär ist, und >und <jeweils rechte und linke bewegliche Schalen darstellen.

Sie müssen die Gesamtstrecke, die die Muschel zurückgelegt hat, ausdrucken oder zurückgeben, sobald der allerletzte Ziegelsteinblock (aka 1) gebrochen wurde.

Die Ausgabe für 39ist 7und die Änderungen im Level sehen folgendermaßen aus:

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

Ebenso 6lautet die Ausgabe für 1:

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

Der kürzeste Code in Bytes gewinnt.

Als Referenz sind hier die Ausgänge für Eingänge 0zu 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

Und hier sind die Ausgänge bis zum Eingang 1000.

Calvins Hobbys
quelle

Antworten:

6

CJam, 29 26 24 Bytes

Danke an Sp3000 für das Speichern von 3 Bytes.

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

Testsuite. (Dies gibt alle Ergebnisse von 0 bis zu der auf STDIN angegebenen Ganzzahl aus.)

Erläuterung

Dies dreht die Spezifikation ein wenig um: Anstatt die Shell durch die Binärzeichenfolge zu bewegen, verschieben wir die Binärzeichenfolge und kehren sie um, sodass die Shell immer vorne ist und nach rechts zeigt:

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
quelle
5

Pyth, 24 Bytes

&.WsH_XZeaYxZ1 0jQ2ssPBY

Probieren Sie es online aus: Demo oder Test Suite

Der folgende 22-Byte-Code sollte ebenfalls ausreichen. Wegen eines Fehlers im Pyth-Compiler funktioniert es derzeit nicht.

&u_XGeaYxG1ZjQ2)ssPBPY

edit: Fehler behoben, aber die Lösung zählt natürlich nicht.

Probieren Sie es online aus: Demo oder Test Suite

Erläuterung:

Im Wechsel von vorne und hinten mache ich folgendes:

  • Ich suche eine 1
  • Merken Sie sich diesen Index, indem Sie ihn in eine Liste aufnehmen
  • Aktualisiere diese 1 zu einer 0

Wenn keine Einsen mehr übrig sind, berechne ich die Entfernung. Wichtig ist: Die Shell verschiebt jeden Abstand in der Liste zweimal (vorwärts und rückwärts), mit Ausnahme des letzten Abstands.

&.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
quelle