Kann Mario zum Ende dieser Karte gehen

13

Erstellen Sie ein Programm, das anhand einer Eingabe des Pfads festlegt, ob Mario das Ende erreichen kann, das Evon Anfang an mit gekennzeichnet ist S.

Ein Pfad sieht ungefähr so ​​aus:

S = E
=====

In einem Pfad sind die verschiedenen Symbole und was sie darstellen:

  • =: Wand / Boden / Decke. Mario kann nicht durch eine Wand gehen und kann nicht über einen Boden fallen oder über eine Decke springen (er würde sich auf den Kopf schlagen)
  • (Weltraum): Luft. Mario kann das durchgehen und durchspringen und durchfallen
  • S: Luft, außer zu zeigen, wo Mario beginnt. Dies wird immer in der äußersten linken Spalte des Eingangs in Bodennähe angezeigt.
  • E: Luft, außer zu zeigen, wo Mario bekommen will. Dies wird immer in der äußersten rechten Spalte des Eingangs in Bodennähe angezeigt.

Die Eingabe wird an jeder Stelle Leerzeichen enthalten, an der Mario laufen könnte.

Mario kann sich nur vorwärts bewegen; In diesem Beispiel kann Mario das Ziel nicht erreichen

S
===

 ===
   E
====

noch kann er in diesem

    E
   ==
== 
  #==
==
   ==
==
S  ==
======

Er kann jedoch den mit gekennzeichneten Bereich erreichen #(der in der Eingabe nicht angezeigt wird), da er bis zu vier Zellen hoch springen kann. Mario ist übermenschlich. Ein weiteres Beispiel für seine Übermenschlichkeit:

S
=
=
=
=
=
= #
= =
=
=
=
=     E
=======

Mario kann das erreichen, Eindem er die große Distanz verliert, überlebt und ruhig dahin läuft E. Beachten Sie, dass er das nicht erreichen kann #, da Mario gerade nach unten fällt.

Mario kann sehr hoch springen , aber im Vergleich nicht sehr weit nach vorne.

S   E
== ==
 = =

Mario mag versuchen, die Lücke zu überspringen, aber er wird scheitern und direkt hineinfallen. Er kann das Ende nicht erreichen.

Mario kann das Ziel in all diesen Beispielen erreichen:

 E
 =
 =
 =
S=
==

 =
 =   E
S=   =
==   =
 =   =
 =====

S
=






=  E
====

Dies ist Codegolf, so dass nur wenige Bytes gewinnen!

TuxCrafting
quelle
2
Im fallenden Beispiel erwähnen Sie, dass "er das nicht erreichen kann #, weil Mario gerade nach unten fällt." Wenn ich das richtig ansehe, fällt er dann nicht direkt auf das #? Sind Sprünge auch als maximal 4 Leerzeichen und maximal 1 Leerzeichen definiert?
GuitarPicker
4
@GuitarPicker Ich dachte zuerst, dass auch, aber wenn Sie genau hinschauen, können Sie sehen, dass es eine andere Spalte von Räumen vor der Spalte mit dem gibt #. Zur zweiten Frage: Ich bin nicht OP, aber ich vermute, Sie haben recht. (das habe ich in meiner Lösung angenommen)
KarlKastor
1
Wird im dritten Beispiel (das Marios Sprunghöhe demonstriert) Enicht in der Spalte ganz rechts angezeigt, da sich das Bodenniveau vom Rest der Karte aus um eins nach rechts erstreckt.
Taylor Lopez
1
@Joffan:Mario cannot walk through wall , and cannot fall past a floor, or jump past a ceiling
Titus
1
@Titus Ich denke an Mario, der in die klare Luft springt und eine Auswahl verschiedener Stockwerke hat, auf denen er landen kann - kann er in den unteren gelangen?
Joffan

Antworten:

11

Unterhose , 38 27 25 Bytes

S>(`=<<`P{1,5}>`P>`P*)+#E

Erfordert, dass die Eingabe in ein Rechteck aufgefüllt wird, sodass in jeder Zelle Leerzeichen vorhanden sind, die Mario durchlaufen muss (möglicherweise mit einer führenden Zeile voller Leerzeichen). Druck entweder eine Zeichenfolge , die den gültigen Pfad (das schließt S, Eund alles =ging auf mit Ausnahme der letzten) oder nichts , wenn kein Pfad vorhanden ist .

Teste es hier.

Erläuterung

Slip war Sp3000's Einstieg in unsere 2D-Pattern-Matching-Sprachdesign-Herausforderung. Es ist ein bisschen wie eine 2D-Erweiterung von Regex, bei der Sie dem Motorcursor Anweisungen geben können, wann er nach links oder rechts abbiegen darf oder muss. Es hat auch eine praktische Funktion, mit der Sie das Vorrücken des Cursors verhindern können, sodass Sie eine einzelne Position zweimal hintereinander (mit unterschiedlichen Mustern) abgleichen können.

Slip hat nichts Vergleichbares wie Lookarounds in Regex, aber da Sie mehrmals über eine beliebige Position fahren können, können Sie den Zustand einfach testen und dann zurückkehren. Wir verwenden dies, um sicherzustellen, dass wir nur auf dem Boden springen, indem wir uns nach jedem Schritt in das Bodenplättchen bewegen.

S           Match the starting position S.
>           Turn right, so that the cursor points south.
(           One or more times... each repetition of this group represents
            one step to the right.
  `=          Match a = to ensure we've ended up on ground level before.
  <<          Turn left twice, so that the cursor points north.
  `P{1,5}     Match 1 to 5 non-punctuation characters (in our case, either space,
              S or E, i.e. a non-ground character). This is the jump.
  >           Turn right, so that the cursor points east.
  `P          Match another non-ground character. This is the step to the right.
  >           Turn right, so that the cursor points south.
  `P*         Match zero or more non-ground characters. This is the fall.
)+
#           Do not advance the cursor before the next match.
E           Match E, ensuring that the previous path ended on the exit.
Martin Ender
quelle
9

Java 234 230 221 216 208 207 205 179 Bytes

Schau, ich habe C und Python besiegt? Ich habe wahre Transzendenz unter Sterblichen erreicht! Abgesehen von allen Witzen war dies eine lustige Herausforderung. Die folgende Funktion nimmt Eingaben als Array von Spaltenzeichenfolgen mit jeweils derselben Länge entgegen. Wenn dies gegen die Regeln verstößt, lass es mich bitte wissen. Es gibt 1 aus, was einen erfolgreichen Mario-Lauf bedeutet, und jeden anderen Wert, der einen fehlgeschlagenen Mario-Lauf impliziert.

int m(String[]a){int l=a.length-1,z=a[l].indexOf(69),m=a[0].indexOf(83),i=1,x;a[l]=a[l].replace("E"," ");for(;i<=l;m=x,i++){if(m-(x=a[i].indexOf('='))>3|x<1)return-1;}return m-z;}

Hier ist die ältere Logik (die der aktuellen Version ähnelt) mit Beispielgebrauch und Ausgabe. Plus einige Kommentare zur Erklärung der Logik

/**
 *
 * @author Rohans
 */
public class Mario {

    int m(String[] a) {
//declare variables for the finish the location of mario and the length
        int z, l = a.length - 1, m = a[0].indexOf("S");
        //treat the exit as a space
        z = a[l].indexOf("E");
        a[l] = a[l].replaceAll("E", " ");
        //go through the map
        for (int i = 1, x, r = 1; i <= l; i++) {
            //if mario can safely jump to the next platform (it picks the highest one)
            if (((x = a[i].indexOf("=")) != 0 && (x = a[i].indexOf(" =")) == -1) || m - x > 4) {
                return 0;
            }
            //adjust marios y location
            m = x;
        }
        //make sure mario made it to the end of the level
        return m == z ? 1 : 0;
    }

    public static void MarioTest(String... testCase) {
        System.out.println(new Mario().m(testCase) == 1 ? "Mario made it" : "Mario did not make it");
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        MarioTest("   S=", "=====", "     =", "     =", "=   =", "     E=");

    }

}
Rohan Jhunjhunwala
quelle
Lassen Sie uns diese Diskussion im Chat fortsetzen .
Betseg
@ KarlKastor, du hast mich erwischt, aber der angegebene Testfall ist korrekt. Das Problem ist, dass die Operation nicht genau festlegte, ob es bei jedem Schritt mehrere Möglichkeiten für den Mario gibt
Rohan Jhunjhunwala,
Nun, ich nahm an, dass dies der Fall sein würde, weil ich immer die allgemeinere Version annehmen würde, wenn keine zusätzlichen Einschränkungen angegeben würden.
Karl Kastor
@ KarlKastor yeah ur right
Rohan Jhunjhunwala
7

Python, 260, 239, 222, 215 209 206 Bytes,

versuche es auf ideone (mit testfällen)

f=lambda m,y=-1,x=0:f(m,m[0].find("S"))if y<0else y<len(m[0])-1and x<len(m)and m[x][y]!="="and(m[x][y]=="E"or m[x][y+1]=="="and any(f(m,y-i,x+1)for i in range(5)[:(m[x][y::-1]+"=").find("=")])or f(m,y+1,x))

anrufen wie: f([' S=', ' E='])

Klebenotizzettel:

Angenommen, die Eingabe besteht, wie bei einigen anderen Lösungen, aus einer Reihe von Spaltenzeichenfolgen, die jeweils mit einem "" beginnen.

Wrapper für altes Eingabeformular: g=lambda x:f(map("".join,zip(*([" "*x.index("\n")]+x.split("\n")))))

Außerdem habe ich einen Fehler behoben, durch den Mario durch Blöcke über ihm springen konnte.

ungolfed version mit erklärungen:

fruft sich rekursiv in alle Richtungen auf, in die sich Mario bewegen kann y,x. Es kehrt zurück, Truewenn es das erreicht "E"nd, das dann alle Funktionsaufrufe durchläuft, bis es gschließlich zurückkehrt True.

def g(x):
    #create a array of strings which are the rows of the input
    global m
    m=x.split("\n")
    m=[" "*len(m[0])]+m # because Mario can jump over sometimes
    #Mario starts at the S
    return f([i for i,a in enumerate(m) if a[0]=="S"][0],0)

def f(y,x):
    #print y,x
    if y>len(m)-2 or x>=len(m[0]) or y<0: return False #out of bounds
    if m[y][x]=="E":return True #Reached the goal
    if m[y][x]=="=":return False #We got stuck inside a wall
    if m[y+1][x]=="=": #if you have ground under your feet
        for i in range(5): #jump max 4
            if f(y-i,x+1): #go one forward and try to go further from there
                return True
    return f(y+1,x) ##fall down
KarlKastor
quelle
Wenn das Springen nicht hilft, fällst du durch den Boden. In einem elsevor dem letzten return?
Titus
5

Schnecken , 41 37 29 Bytes

Danke an feersum für die Hilfe, um überlappende Pfade zu vermeiden und 4 Bytes zu sparen.

=\S(^=d=\=u\ ,4(r!\=d.),r),\E

Erfordert, dass die Eingabe in ein Rechteck aufgefüllt wird, sodass in jeder Zelle Leerzeichen vorhanden sind, die Mario durchlaufen muss (möglicherweise mit einer führenden Zeile voller Leerzeichen).

Probieren Sie es online!

Erläuterung

Snails war feersums Einstieg in unsere 2D-Pattern-Matching-Sprachdesign-Herausforderung. Wie Slip ähnelt es auch Regex, aber der Hauptunterschied besteht darin, dass a) dieses Assertions (Lookarounds) unterstützt und b) abgesehen von diesen Assertions keine Zelle im Raster zweimal durchlaufen werden kann. Das macht dieses Problem etwas knifflig, da es Fälle gibt, in denen Mario in ein Loch fallen und wieder herausspringen muss, zB:

S E
= =
===

Abgesehen von diesen Unterschieden unterscheidet sich auch die Syntax der beiden Sprachen erheblich.

Um das Problem zu umgehen, dass wir eine Zelle nicht zweimal durchlaufen können, wechseln wir immer einen horizontalen Schritt mit einem vertikalen Schritt. Dies bedeutet jedoch, dass wir einen Sturz bewältigen müssen, bevor wir über den Sims treten. Stürze werden also technisch gesehen durch Bodenplatten verlaufen, aber wir werden sicherstellen, dass sie nur in der Nähe von Freiflächen auftreten.

=\S        Ensure that the match starts on an S, without actually matching it.
(          This group matches zero or more steps to the right (with a potential
           vertical step after each one).
  ^=         Match a non-ground cell, stepping right (on the first iteration,
             there is no step yet, so this matches the S).
  d=\=       Ensure that there's a ground tile below, so that the step ends on
             a valid position.
  u\ ,4      Match 0 to 4 spaces going up. This the optional jump.
  (          This group matches zero or more steps down, if a fall is valid here.
    r!\=       Ensure that there is no ground-tile right of the current cell.
    d.         Take one step down onto any character.
  ),
  r          Reset the direction to right for the next iteration.
),
\E        Match the exit.
Martin Ender
quelle
4

C 256 236 213 197 Bytes

20 Bytes gespeichert durch "Dies wird immer in der Spalte ganz links der Eingabe angezeigt "
23 Bytes gespeichert dank @ RohanJhunjhunwalas spaltenbasiertem System

Probiere es auf ideone mit Testfällen ...

k,y,x,h;f(v,l)char**v;{h=strlen(*v);x=strcspn(*v,"S");while(y<l&x<h)if(v[y][x]==69)return 0;else if(v[y][x+1]^61)x++;else{if(v[y+1][x]==61)while(k<4)if(v[y+1][x-++k]^61){x-=k;break;}y++;}return 1;}

Verwendung:

$ ./mario "S=" " =" " =" " =" "E="
main(c,v)char**v;{printf("%s",f(v+1,c-1)==0?"true":"false");}

Ungolfed mit Erklärung:

k,y,x,h; //omitting int for saving 4 bytes, global variables initialize as 0 by default
f(v,l)char**v;{ //saving 2 bytes
    h=strlen(v[0]); //get height of map
    x=strcspn(v[0],"S"); //where is start point?
    while(y<l&&x<h) //while not out of bounds
        if(v[y][x]==69)return 0; //if we hit end return 0 (69 is ASCII E)
        else if(v[y][x+1]!=61)x++; //we fall one block if there isn't floor underneath us (61 is ASCII =)
        else{
            if(v[y+1][x]==61) //if there is a wall in front of us
                while(k<4) //start counting
                    if(v[y+1][x-++k]!=61){ //if found a way
                        x-=k; //go to there
                        break; //we don't want to jump multiple times
                    }
            y++; //finally, walk one block forwards
        }
    return 1; //if out of bounds
}
betseg
quelle
Ideone sagen, dass es einen Laufzeitfehler gibt
TuxCrafting
6
Warten Sie, Sie codieren auf dem Handy ಠ_ಠ
TuxCrafting
4
Ja, ich habe Cola auf meinem Laptop verschüttet: P
betseg
1
(Nicht zu gemein zu betseg , nur Fairness zu gewährleisten) @ TùxCräftîñg: Ist diese Lösung kompatibel mit Ihrer Herausforderung , weil es eine Reihe von Strings (bereits aufgeteilt auf „\ n“) hat und hat auch als Eingabe die Länge und Breite der Karte (nicht Teil der Eingabe in Ihrer Herausforderung)?
Karl Kastor
2

PHP, 399 338 284 265 251 Bytes

<?function w($m,$p){$w=strpos($m,"
")+1;if($p>strlen($m)|($p%$w)>$w-2|$p<0|'='==$m[$p])return 0;if('E'==$m[$p])die(1);if('='!=$m[$p+$w])return w($m,$p+$w);else for(;$z<5&'='!=$m[$q=$p-$w*$z];$z++)if(w($m,$q+1))die(1);}die(w($m=$argv[1],strpos($m,S)));

Erwartet Eingaben als Befehlszeilenargument mit Zeilenumbrüchen und nachgestellten Leerzeichen in jeder Zeile im Unix-Stil und gibt den Exit-Code 1für Erfolg und 0Misserfolg zurück

Aufschlüsselung nach Funktion

function w($m,$p) // function walk
{
    $w=strpos($m,"\n")+1;
    if($p<0|$p>strlen($m)|($p%$w)>$w-2  // too high / too low / too far right
        | '='==$m[$p]                   // or inside a wall
    )return 0;
    if('E'==$m[$p])return 1;            // Exit found
    if('='!=$m[$p+$w])return w($m,$p+$w); // no wall below: fall down
    else for($z=0;$z<5                  // else: jump
        & '='!=$m[$q=$p-$w*$z]          // do not jump through walls
        ;$z++)
        if(w($m,$q+1))                  // try to walk on from there
            return 1;
    // no success, return failure (NULL)
}
function m($i){$argv=[__FILE__,$i];
    return w($m=$argv[1],strpos($m,S));     // walk through map starting at position of S
}

Tests (auf Funktion m)

$cases=[
    // examples
    "S = E\n=====",0,
    "S   \n=== \n    \n ===\n   E\n====",0,
    "    E \n   == \n==    \n   == \n==    \n   == \n==    \nS  == \n======",0,
    "S      \n=      \n=      \n=      \n=      \n=      \n=      \n= =    \n=      \n=      \n=      \n=     E\n=======",1,
    "S   E\n== ==\n = = ",0,
    " E\n =\n =\n =\nS=\n==",1,
    "      \n =    \n =   E\nS=   =\n==   =\n =   =\n =====",1,
    "S   \n=   \n    \n    \n    \n    \n    \n    \n=  E\n====",1,
    // additional cases
    "S \n= \n=E",1,
    " == \n == \n    \nS==E\n==  ",1
];
echo'<table border=1><tr><th>input</th><th>output</th><th>expected</th><th>ok?</th></tr>';
while($cases)
{
    $m=array_shift($cases);
    $e=array_shift($cases);
    $y=m($m);
    $w=strpos($m,"\n");
    echo"<tr><td><div style=background-color:yellow;width:",$w*8,"px><pre>$m</pre></div>width=$w</td>
        <td>$y</td><td>$e</td><td>",$e-$y?'N':'Y',"</td></tr>";
}
echo'</table>';
Titus
quelle
1
Wer auch immer: Lassen Sie mich bitte wissen, warum Sie dies abgelehnt haben?
Titus
2

Ruby, 153 147 Bytes

Sorry, Java ... dein Platz als beste Nicht-Golf-Sprache für den Job wird übernommen!

Die Eingabe ist eine Liste von Spaltenzeichenfolgen, denen ein einzelnes Leerzeichen vorangestellt ist. Dies entspricht der Art, wie die Slip- und Snails-Lösungen erfordern, dass ihre Eingaben mit einem leeren Rechteck aufgefüllt werden.

Probieren Sie es online!

f=->m,j=0,s=p{c,n=m[j,2]
s||=c=~/S/
e=c=~/E/
s+=1 while(k=c[s+1])&&k!=?=
s==e||(0..4).any?{|i|k&&s>=i&&c[s-i,i]!~/=/&&n&&n[s-i]!=?=&&f[m,j+1,s-i]}}
Wert Tinte
quelle
nooooo .... aber du hast meine Methode der säulenförmigen Zeichenfolgen "ausgeliehen"
Rohan Jhunjhunwala
1
Nun, ich meine, alle coolen Kids haben es schon gemacht. Könnte später eine zeilenbasierte Lösung entwickeln, indem Sie eine "Schnellreparatur" durchführen, um Zeilen in Spalten zu ändern, damit mein aktueller Code um 10 Byte an Java verliert, aber eine tatsächliche Lösung könnte trotzdem kürzer sein
Value Ink
2

Schmutz, 46 Bytes (nicht konkurrierend)

A=\E|[S ]&<\ {,-4}/0/./* \ /*/A/\=/./*>
n`\S&A

Ich habe Grime mehrmals aktualisiert, nachdem diese Herausforderung veröffentlicht wurde, sodass diese Antwort nicht zum Gewinnen berechtigt ist. Einige der Änderungen sind so neu, dass ich sie nicht in TIO integrieren konnte, aber sobald ich sie vorgenommen habe, können Sie das Programm ausprobieren . In jedem Fall enthält mein Repository eine Version, die diesen Code korrekt verarbeitet.

Das Programm gibt aus, 1ob Mario das Ziel erreichen kann und 0wenn nicht. Die Eingabe muss Leerzeichen an allen Stellen enthalten, die Mario besuchen muss. Für allgemeine Eingaben habe ich die folgende 57-Byte- Lösung:

A=\E|[ \bS]&<[ \b]{,-4}/0/[]/* [ \b]/*/A/\=/[]/*>
nb`\S&A

Erläuterung

Die allgemeine Erklärung ist, dass das Ain der ersten Zeile definierte Nicht-Terminal mit einem 1 × 1- Teilrechteck der Eingabe übereinstimmt, in dem Mario das Ziel erreichen kann. Awird entweder als das Literal E(Mario ist bereits am Ziel) oder als ein 1 × 1- Muster definiert, das sich in der linken Spalte eines 2 × n- Rechtecks ​​befindet und einen gültigen Mario-Sprung zu einer anderen Übereinstimmung Ain der rechten Spalte enthält. Die zweite Zeile zählt die Anzahl der Übereinstimmungen A, die auch das Startzeichen enthalten S, und gibt dieses aus.

Hier ist eine Aufschlüsselung des Codes:

A=\E|[ S]&<\ {,-4}/0/./* \ /*/A/\=/./*>
A=                                       Define A as
  \E|                                    a literal E, or
     [ S]&                               a literal space or S
          <                           >  contained in a larger rectangle
                                         that this bracketed expression matches.
           \ {,-4}/0/./*                 Left half of the bracketed expression:
           \ {,-4}                        Rectangle of spaces with height 0-4,
                  /                       below that
                   0                      the 1x1 rectangle we're currently matching,
                    /.                    below that any 1x1 rectangles
                      /*                  stacked any number of times vertically.
                         \ /*/A/\=/./*   Right half of the bracketed expression:
                         \ /*             Spaces stacked vertically,
                             /A           below that another match of A,
                               /\=        below that a literal =,
                                  /./*    below that 1x1 rectangles stacked vertically.

Die Idee ist, dass der \ {,-4}Teil links dem Raum entspricht, durch den Mario nach oben springt, und der \ /*Teil rechts dem Raum, durch den er dann fällt. Wir verlangen, dass er in einem Match landet, das A(da wir das Ziel erreichen wollen) über einem liegt =. Die vertikalen Stapel unter beiden Spalten garantieren einfach, dass die Spalten die gleiche Höhe haben, sodass wir sie verketten können (das ist, was der einzelne Raum in der Mitte tut). Hier ist ein ASCII-Grafikdiagramm eines Beispielsprungs, unterteilt in die oben genannten Rechtecke und mit Leerzeichen, die durch *s ersetzt werden :

Left column:     Right column:   +---+---+
a = \ {,-4}      d = \ /*        | * | * |
b = 0            e = A           +   +   + d
c = ./*          f = \=          | * | * |
                 g = ./*       a +   +---+
                                 | * | * | e
                                 +   +---+
                                 | * | = | f
                                 +---+---+
                               b | S | = |
                                 +---+   | g
                               c | = | * |
                                 +---+---+

In der zweiten Zeile nlöst die Option die Zählung aller Übereinstimmungen aus, anstatt die erste Übereinstimmung zu finden. In der allgemeinen Lösung können die Leerzeichen auch Sonderzeichen ohne Eingabe seinb bewirkt dass die Eingabe mit Eingabe aufgefüllt wird.

Ich hoffe das alles macht Sinn!

Zgarb
quelle