Mario peut-il aller à la fin de cette carte

13

Créez un programme qui détermine, étant donné une entrée du chemin, si Mario peut atteindre la fin, désigné par E, dès le début, désigné par S.

Un chemin ressemblera à ceci:

S = E
=====

Dans un chemin, les différents symboles et ce qu'ils représentent sont:

  • =: mur / sol / plafond. Mario ne peut pas traverser un mur et ne peut pas tomber devant un sol ou sauter par-dessus un plafond (il se heurterait la tête)
  • (espace): air. Mario peut traverser cela, sauter à travers et tomber à travers
  • S: air, sauf pour montrer où commence Mario. Cela apparaîtra toujours dans la colonne la plus à gauche de l'entrée, au niveau du sol.
  • E: air, sauf pour montrer où Mario veut aller. Cela apparaîtra toujours dans la colonne la plus à droite de l'entrée, au niveau du sol.

L'entrée aura des espaces à chaque endroit où Mario pourrait marcher.

Mario ne peut que progresser; dans cet exemple, Mario ne peut pas atteindre l'objectif

S
===

 ===
   E
====

il ne peut pas non plus dans celui-ci

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

Cependant, il peut atteindre l'espace désigné par #(qui n'apparaîtra pas en entrée), car il peut sauter jusqu'à quatre cellules de haut; Mario est surhumain. Comme autre exemple de sa surhumanité:

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

Mario peut accéder à la Edistance en parcourant la grande distance, en survivant et en marchant calmement vers E. Notez qu'il ne peut pas atteindre le #, car Mario tombe droit vers le bas.

Mario peut sauter très haut, mais pas très loin en comparaison.

S   E
== ==
 = =

Mario peut tenter de sauter l'écart, mais il échouera et tombera directement. Il ne peut pas atteindre la fin.

Mario peut atteindre l'objectif dans tous ces exemples:

 E
 =
 =
 =
S=
==

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

S
=






=  E
====

C'est le golf de code, donc le moins d'octets gagne!

TuxCrafting
la source
2
Dans l'exemple qui tombe, vous mentionnez qu '"il ne peut pas atteindre le #, car Mario tombe tout droit". Si je vois cela correctement, ne tomberait-il pas directement sur le #? De plus, les sauts sont-ils définis comme un maximum de 4 espaces vers le haut et un maximum de 1 espace, n'est-ce pas?
GuitarPicker
4
@GuitarPicker Je pensais qu'au début aussi, mais si vous regardez attentivement, vous pouvez voir qu'il y a une autre colonne d'espaces avant la colonne avec le #. Quant à la deuxième question: je ne suis pas OP mais je suppose que vous avez raison. (c'est ce que j'ai supposé dans ma solution)
KarlKastor
1
Dans le troisième exemple (démontrant la hauteur de saut de Mario), En'apparaît pas dans la colonne la plus à droite car le niveau du sol s'étend de un à droite à partir du reste de la carte.
Taylor Lopez
1
@Joffan:Mario cannot walk through wall , and cannot fall past a floor, or jump past a ceiling
Titus
1
@Titus Je pense à Mario qui saute en l'air et a le choix entre différents étages pour atterrir - peut-il arriver à l'étage inférieur?
Joffan

Réponses:

11

Slip , 38 27 25 octets

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

Nécessite que l'entrée soit complétée par un rectangle de sorte qu'il y ait des espaces dans chaque cellule que Mario doit traverser (potentiellement avec une ligne de tête pleine d'espaces). Imprime soit une chaîne représentant le chemin valide (qui inclut S, Eet tous les parcours =sauf le dernier) ou rien si aucun chemin n'existe.

Testez-le ici.

Explication

Slip était l'entrée de Sp3000 dans notre défi de conception de langage de correspondance de motifs 2D. C'est un peu comme une extension 2D de regex où vous pouvez donner des instructions au curseur du moteur quand il est autorisé ou nécessaire de faire des virages à gauche ou à droite. Il a également une fonction pratique où vous pouvez empêcher le curseur d'avancer, vous permettant de faire correspondre une seule position deux fois de suite (avec des motifs différents).

Le glissement n'a pas quelque chose de comparable à des contournements dans l'expression régulière, mais comme vous pouvez vous déplacer plusieurs fois sur n'importe quelle position, il suffit de tester la condition, puis de revenir. Nous utilisons cela pour nous assurer que nous ne sautons que sur le sol en nous déplaçant dans la tuile au sol après chaque étape.

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
la source
9

Java 234230221216208207205179179 octets

Ecoute, j'ai battu C et python? J'ai atteint la vraie transcendance parmi les mortels! Toutes blagues à part, ce fut un défi amusant. La fonction suivante prend en entrée un tableau de chaînes de colonnes ayant chacune la même longueur. Si cela est contraire aux règles, veuillez me le faire savoir. Il renvoie 1, ce qui signifie une exécution mario réussie, et toute autre valeur impliquant une exécution mario échouée.

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

Voici l'ancienne logique (qui est similaire à la version actuelle) avec des exemples d'utilisation et de sortie. Plus quelques commentaires expliquant la logique

/**
 *
 * @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
la source
Continuons cette discussion dans le chat .
betseg
@KarlKastor, vous m'avez bien compris, mais le cas de test donné est correct. Le problème est que l'op n'a pas précisé s'il y aurait plusieurs façons pour le mario d'aller à chaque étape
Rohan Jhunjhunwala
Eh bien, j'ai supposé qu'il y en aurait parce que je supposerais toujours la version la plus générale si des contraintes supplémentaires ne sont pas spécifiées.
KarlKastor
@KarlKastor yeah ur right
Rohan Jhunjhunwala
7

Python, 260 239 222 215 209 206 octets,

essayez-le sur ideone (avec des cas de 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))

appeler comme: f([' S=', ' E='])

notes de mise à jour:

Maintenant, comme certaines des autres solutions, suppose que l'entrée est un tableau de chaînes de colonnes, chacune commençant par un ""

Wrapper pour l'ancien formulaire de saisie: g=lambda x:f(map("".join,zip(*([" "*x.index("\n")]+x.split("\n")))))

De plus, j'ai corrigé un bug où Mario pouvait sauter à travers les blocs au-dessus de lui.

version non golfée avec explications:

fs'appelle récursivement dans toutes les directions vers lesquelles Mario peut se déplacer y,x. Il revient Truequand il atteint le "E"nd, qui reprend ensuite tous les appels de fonction jusqu'à ce gqu'il revienne finalement 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
la source
Si sauter ne vous aide pas, vous tombez par terre. Ajouter un elseavant la finale return?
Titus
5

Escargots , 41 37 29 octets

Merci à feersum pour son aide à éviter les chemins qui se chevauchent et pour avoir économisé 4 octets.

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

Nécessite que l'entrée soit complétée par un rectangle de sorte qu'il y ait des espaces dans chaque cellule que Mario doit traverser (potentiellement avec une ligne de tête pleine d'espaces).

Essayez-le en ligne!

Explication

Snails était l'entrée de feersum dans notre défi de conception de langage de correspondance de motifs 2D. Comme Slip, il est également similaire à regex, mais la principale différence est que a) celui-ci prend en charge les assertions (lookarounds) et b) en dehors de ces assertions, il n'est pas possible de parcourir deux cellules de la grille deux fois. Cela rend ce problème un peu délicat, car il y a des cas où Mario doit tomber dans un trou et sauter en arrière, par exemple:

S E
= =
===

En dehors de ces différences, la syntaxe des deux langues diffère également beaucoup.

Pour contourner le problème selon lequel nous ne pouvons pas traverser une cellule deux fois, nous alternons toujours une étape horizontale avec une étape verticale. Cependant, cela signifie que nous devons gérer une chute avant de franchir le rebord. Ainsi, les chutes passeront techniquement par des tuiles au sol, mais nous veillerons à ce qu'elles ne se produisent qu'à côté d'un espace ouvert.

=\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
la source
4

C, 256 236 213 197 octets

20 octets enregistrés par "Cela apparaîtra toujours dans la colonne la plus à gauche de l'entrée"
23 octets enregistrés grâce au système basé sur les colonnes de @ RohanJhunjhunwala

Essayez-le sur ideone, avec des cas de 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;}

Usage:

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

Non golfé avec explication:

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
la source
Ideone dit qu'il y a une erreur d'exécution
TuxCrafting
6
Attendez, vous
codez
4
Oui, j'ai renversé de la coke sur mon ordinateur portable: P
betseg
1
(Ne pas être méchant de parier , juste pour assurer l'équité) @ TùxCräftîñg: cette solution est-elle conforme à votre défi car elle prend un tableau de chaînes (déjà divisé sur "\ n") et a également comme entrée la longueur et la largeur du carte (ne fait pas partie de la contribution de votre défi)?
KarlKastor
2

PHP, 399 338 284 265 251 octets

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

attend l'entrée comme argument de ligne de commande avec des sauts de ligne de style Unix et des espaces de fin dans chaque ligne, renvoie le code de sortie 1pour le succès, 0pour l'échec

panne pour fonctionner

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 (sur la fonction 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
la source
1
à qui que ce soit: Voulez-vous s'il vous plaît laissez-moi savoir pourquoi vous avez voté pour cela?
Titus
2

Rubis, 153 147 octets

Désolé, Java ... votre place en tant que meilleure langue non golfique pour le travail est prise en charge!

L'entrée est une liste de chaînes de colonnes, précédée d'un espace unique dans le style de la façon dont les solutions Slip et Snails nécessitent que leurs entrées soient complétées par un rectangle d'espace vide.

Essayez-le en ligne!

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]}}
Encre de valeur
la source
nooooo .... mais tu as "emprunté" ma méthode de cordes en colonnes
Rohan Jhunjhunwala
1
Eh bien, je veux dire, tous les enfants sympas le faisaient déjà. Pourrait créer une solution basée sur les lignes plus tard, en faisant une "solution rapide" pour modifier les lignes en colonnes afin de garder mon code actuel perd à votre Java de 10 octets, mais une solution réelle peut être plus courte malgré tout
Value Ink
2

Grime, 46 octets (non concurrent)

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

J'ai mis à jour Grime plusieurs fois après la publication de ce défi, cette réponse n'est donc pas éligible pour gagner. Certains des changements sont si nouveaux que je n'ai pas pu les intégrer à TIO, mais une fois que je le fais, vous pouvez essayer le programme . Dans tous les cas, mon référentiel contient une version qui gère correctement ce code.

Le programme imprime 1si Mario peut atteindre l'objectif, et 0sinon. L'entrée doit contenir des espaces dans tous les endroits que Mario doit visiter. Pour les entrées générales, j'ai la solution suivante de 57 octets :

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

Explication

L'explication de haut niveau est que le non-terminal A, défini sur la première ligne, correspond à un sous-rectangle 1 × 1 de l'entrée où Mario peut atteindre le but. Aest défini soit comme le littéral E(Mario est déjà au but), soit comme un motif 1 × 1 qui se trouve dans la colonne de gauche d'un rectangle 2 × n contenant un saut Mario valide vers une autre correspondance de Adans la colonne de droite. La deuxième ligne compte le nombre de correspondances Aqui contiennent également le caractère de départ Set l'imprime.

Voici une ventilation du code:

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'idée est que la \ {,-4}partie de gauche correspond à l'espace à travers lequel Mario saute vers le haut, et la \ /*partie de droite correspond à la goulotte d'espace où il tombe ensuite. Nous exigeons qu'il atterrisse sur un match de A(puisque nous voulons atteindre le but) qui est au-dessus d'un =. Les piles verticales sous les deux colonnes garantiront simplement que les colonnes ont la même hauteur, afin que nous puissions les concaténer (c'est ce que fait l'espace unique au milieu). Voici un diagramme d'art ASCII d'un exemple de saut, divisé en rectangles susmentionnés et avec des espaces remplacés par *s:

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

Sur la deuxième ligne, l'option n déclenche le comptage de toutes les correspondances, au lieu de trouver la première correspondance. Dans la solution générale, les espaces peuvent également être des caractères spéciaux hors entrée et une optionb entraîne le remplissage de l'entrée avec des caractères hors entrée.

J'espère que tout cela a du sens!

Zgarb
la source