Mario può andare alla fine di questa mappa


13

Crea un programma che determina, dato un input del percorso, se Mario può raggiungere la fine, indicato da E, sin dall'inizio, indicato daS .

Un percorso sarà simile a questo:

S = E
=====

In un percorso, i vari simboli e ciò che rappresentano sono:

  • =: parete / pavimento / soffitto. Mario non può attraversare il muro e non può oltrepassare un pavimento o saltare oltre un soffitto (avrebbe colpito la sua testa)
  • (spazio): aria. Mario può attraversarlo, saltarci dentro e cadere
  • S: aria, tranne mostrare dove inizia Mario. Apparirà sempre nella colonna più a sinistra dell'ingresso, a livello del suolo.
  • E: aria, tranne mostrare dove Mario vuole arrivare. Apparirà sempre nella colonna più a destra dell'ingresso, a livello del suolo.

L'ingresso avrà spazi in ogni luogo in cui Mario potrebbe camminare.

Mario può solo andare avanti; in questo esempio Mario non può raggiungere l'obiettivo

S
===

 ===
   E
====

né può in questo

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

Tuttavia, può raggiungere lo spazio indicato da #(che non apparirà in input), perché può saltare fino a quattro celle in alto; Mario è sovrumano. Come altro esempio della sua superumanità:

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

Mario può arrivare Ecadendo a grande distanza, sopravvivendo e camminando con calma verso E. Nota che non può raggiungere il #, perché Mario cade dritto.

Mario può saltare molto in alto, ma non molto lontano in confronto.

S   E
== ==
 = =

Mario può tentare di colmare il divario, ma fallirà e cadrà dritto. Non può raggiungere la fine.

Mario può raggiungere l'obiettivo in tutti questi esempi:

 E
 =
 =
 =
S=
==

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

S
=






=  E
====

Questo è il golf del codice, quindi vince il minor numero di byte!


2
Nell'esempio che cade, dici che "non può raggiungere il #, perché Mario cade dritto". Se lo sto visualizzando correttamente, non cadrà direttamente sul #? Inoltre, i salti sono definiti come un massimo di 4 spazi su e un massimo di 1 spazio giusto?
GuitarPicker,

4
@GuitarPicker Ho pensato che all'inizio, ma se guardi da vicino puoi vedere che c'è un'altra colonna di spazi prima della colonna con il #. Per quanto riguarda la seconda domanda: non sono OP ma suppongo che tu abbia ragione. (è quello che ho assunto nella mia soluzione)
KarlKastor,

1
Nel terzo esempio (che dimostra l'altezza di salto di Mario), Enon appare nella colonna più a destra perché il livello del suolo si estende a destra dal resto della mappa.
Taylor Lopez,

1
@Joffan:Mario cannot walk through wall , and cannot fall past a floor, or jump past a ceiling
Tito

1
@Titus Sto pensando a Mario che salta in aria libera e ha una scelta di piani diversi su cui atterrare - può arrivare a quello inferiore?
Joffan,

Risposte:


11

Slip , 38 27 25 byte

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

Richiede che l'input sia riempito con un rettangolo in modo tale che ci siano spazi in ogni cella che Mario deve attraversare (potenzialmente con una linea iniziale piena di spazi). Stampa una stringa che rappresenta il percorso valido (che comprende S, Ee tutte le =camminava sul tranne l'ultimo) o niente se non esiste alcun percorso.

Provalo qui.

Spiegazione

Slip è stato l'ingresso di Sp3000 nella nostra sfida di progettazione del linguaggio di abbinamento di modelli 2D. È un po 'come un'estensione 2D di regex in cui puoi dare istruzioni al cursore del motore quando è permesso o richiesto fare curve a sinistra o a destra. Ha anche una comoda funzione in cui è possibile impedire l'avanzamento del cursore, consentendo di abbinare una singola posizione due volte di fila (con motivi diversi).

Slip non ha qualcosa di paragonabile ai lookaround in regex, ma poiché puoi spostarti su qualsiasi posizione più volte, puoi semplicemente testare la condizione e poi tornare. Usiamo questo per assicurarci di saltare solo quando ci troviamo a terra spostandoci nella tessera terra dopo ogni passo.

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.

9

Java 234 230 221 216 208 207 205 179 byte

Senti, ho battuto C e Python? Ho raggiunto la vera trascendenza tra i mortali! A parte gli scherzi, questa è stata una sfida divertente. La seguente funzione accetta l'input come una matrice di stringhe di colonna della stessa lunghezza. Se questo è contro le regole, per favore fatemelo sapere. Emette 1 che significa una corsa di Mario riuscita e qualsiasi altro valore che implica una corsa di Mario fallita.

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;}

Ecco la logica precedente (che è simile alla versione corrente) con esempio di utilizzo e output. Inoltre alcuni commenti che spiegano la logica

/**
 *
 * @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=");

    }

}



@KarlKastor, mi hai preso, ma il caso di test indicato è corretto. Il problema è che l'opera non ha precisato se ci sarebbero stati molti modi in cui il mario avrebbe potuto procedere ad ogni passo
Rohan Jhunjhunwala,

Bene, ho pensato che ci sarebbe perché avrei sempre assunto la versione più generica se non fossero specificati ulteriori vincoli.
KarlKastor,

@KarlKastor sì, hai ragione
Rohan Jhunjhunwala,

7

Python, 260 239 222 215 209 206 byte,

provalo su ideone (con casi di test)

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))

chiama come: f([' S=', ' E='])

note sulla patch:

Ora, come alcune delle altre soluzioni, presuppone che l'input sia una matrice di stringhe di colonne, ciascuna che inizia con un ""

Wrapper per il vecchio modulo di input: g=lambda x:f(map("".join,zip(*([" "*x.index("\n")]+x.split("\n")))))

Inoltre, ho corretto un bug in cui Mario poteva saltare attraverso i blocchi sopra di lui.

versione non golfata con spiegazioni:

fsi chiama ricorsivamente in tutte le direzioni da cui Mario può spostarsi y,x. Ritorna Truequando raggiunge il "E"nd, che poi ritorna attraverso tutte le chiamate di funzione fino a quando gfinalmente ritorna 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

Se il salto non aiuta, cadi nel terreno. Aggiungi un elseprima della finale return?
Tito

5

Lumache , 41 37 29 byte

Grazie a feersum per un aiuto nell'evitare percorsi sovrapposti e nel salvataggio di 4 byte.

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

Richiede che l'input sia riempito con un rettangolo in modo tale che ci siano spazi in ogni cella che Mario deve attraversare (potenzialmente con una linea principale piena di spazi).

Provalo online!

Spiegazione

Snails è stato l'ingresso di feersum alla nostra sfida di progettazione del linguaggio di abbinamento di modelli 2D. Come Slip è anche simile a regex, ma la differenza principale è che a) supporta asserzioni (lookaround) eb) a parte queste asserzioni, non è possibile attraversare due volte qualsiasi cella della griglia. Ciò rende questo problema un po 'complicato, poiché ci sono casi in cui Mario deve cadere in un buco e saltare indietro, ad esempio:

S E
= =
===

A parte queste differenze, anche la sintassi delle due lingue differisce molto.

Per aggirare il problema che non possiamo attraversare una cella due volte, alterniamo sempre un gradino orizzontale con un gradino verticale. Tuttavia, questo significa che abbiamo bisogno di gestire una caduta prima di scavalcare la sporgenza. Quindi le cadute tecnicamente passeranno effettivamente attraverso le piastrelle di terra ma faremo in modo che avvengano solo vicino allo spazio aperto.

=\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.

4

C, 256 236 213 197 byte

20 byte salvati da "Questo apparirà sempre nella colonna più a sinistra dell'ingresso"
23 byte salvati grazie al sistema basato su colonne di @ RohanJhunjhunwala

Provalo su ideone, con casi di test ...

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;}

Uso:

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

Ungolfed con spiegazione:

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
}

Ideone dice che c'è un errore di runtime
TuxCrafting

6
Aspetta, stai scrivendo sul cellulare mobile_ಠ
TuxCrafting il

4
Sì, ho rovesciato coca cola sul mio laptop: P
Betseg,

1
(Non per essere cattivi con Betseg , solo per garantire l'equità) @ TùxCräftîñg: questa soluzione è conforme alla tua sfida perché prende una serie di stringhe (già divise su "\ n") e ha anche come input la lunghezza e la larghezza del mappa (non parte dell'input nella tua sfida)?
KarlKastor,


2

PHP, 399 338 284 265 251 byte

<?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)));

si aspetta input come argomento della riga di comando con interruzioni di riga di stile unix e spazi finali in ogni riga, restituisce il codice di uscita 1per successo, 0per errore

guasto per funzionare

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
}

test (sulla funzione 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>';

1
a chiunque: per favore fatemi sapere perché avete annullato il voto?
Tito,

2

Rubino, 153 147 byte

Siamo spiacenti, Java ... il tuo posto come miglior lang non golfista per il lavoro è stato assunto!

L'input è un elenco di stringhe di colonna, preceduto da un singolo spazio nello stile di come le soluzioni Slip e Snails richiedono che i loro input siano riempiti con un rettangolo di spazio vuoto.

Provalo 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]}}

nooooo .... ma hai "preso in prestito" il mio metodo di stringhe colonnari
Rohan Jhunjhunwala

1
Beh, voglio dire, tutti i ragazzi fantastici lo stavano già facendo. Potrebbe creare una soluzione basata su righe in un secondo momento, facendo una "correzione rapida" per modificare le righe in colonne per mantenere il mio codice corrente perde a Java di 10 byte, ma una soluzione effettiva potrebbe essere più breve a prescindere
Value Ink

2

Grime, 46 byte (non concorrenti)

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

Ho aggiornato Grime diverse volte dopo che questa sfida è stata pubblicata, quindi questa risposta non è idonea a vincere. Alcune delle modifiche sono così nuove che non sono stato in grado di inserirle in TIO, ma una volta fatto, puoi provare il programma . In ogni caso, il mio repository contiene una versione che gestisce correttamente questo codice.

Il programma stampa 1se Mario può raggiungere l'obiettivo, e in 0caso contrario. L'input deve contenere spazi in tutti i luoghi che Mario deve visitare. Per gli ingressi generali, ho i seguenti 57 byte soluzione a :

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

Spiegazione

La spiegazione di alto livello è che il non terminale A, definito sulla prima riga, corrisponde a un sub-rettangolo 1 × 1 dell'input in cui Mario può raggiungere l'obiettivo. Aè definito come letterale E(Mario è già in porta) o come un modello 1 × 1 che si trova sulla colonna di sinistra di un rettangolo 2 × n contenente un salto di Mario valido in un'altra corrispondenza della Acolonna di destra. La seconda riga conta il numero di corrispondenze Ache contengono anche il carattere iniziale Se lo stampa.

Ecco una suddivisione del codice:

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.

L'idea è che la \ {,-4}parte a sinistra corrisponda allo spazio attraverso il quale Mario salta verso l'alto e la \ /*parte a destra corrisponde allo spazio attraverso il quale poi cade. Abbiamo bisogno che atterri su una partita di A(poiché vogliamo raggiungere l'obiettivo) che è in cima a =. Le pile verticali sotto entrambe le colonne garantiranno semplicemente che le colonne abbiano la stessa altezza, quindi possiamo concatenarle (che è ciò che fa il singolo spazio nel mezzo). Ecco un diagramma di arte ASCII di un salto di esempio, suddiviso nei suddetti rettangoli e con spazi sostituiti da *s:

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

Sulla seconda riga, l'opzione n avvia il conteggio di tutte le partite, invece di trovare la prima corrispondenza. Nella soluzione generale, gli spazi possono anche essere caratteri speciali fuori input e l'opzione bfa sì che l'input sia riempito con caratteri out-of-input.

Spero che tutto ciò abbia un senso!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.