マリオはこのマップの最後に行くことができますか


13

パスの入力が与えられたときに、マリオがで示されるE開始点からで示される終了点に到達できるかどうかを判断するプログラムを作成しますS

パスは次のようになります。

S = E
=====

パスでは、さまざまなシンボルとそれらが表すものは次のとおりです。

  • =:壁/床/天井。マリオは壁を歩くことができず、床を越えたり、天井を飛び越えたりすることはできません(頭にぶつかるでしょう)
  • (スペース):空気。マリオはこれを歩いて、ジャンプして、落ちていくことができます
  • S:空気、マリオが始まる場所を示すことを除く。これは、常に入力の左端の列のグランドレベルに表示されます。
  • E:マリオが行きたい場所を示す以外の空気。これは、常に入力の右端の列のグランドレベルに表示されます。

入力には、マリオが歩くことができるすべての場所にスペースがあります。

マリオは前進しかできない。この例では、マリオは目標を達成できません

S
===

 ===
   E
====

また彼はこれで

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

ただし、#最大4セルまでジャンプできるため、(入力には表示されない)で示されるスペースに到達できます。マリオは超人的です。彼の超人間性の別の例として:

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

マリオはE、遠くに落ちて生き残り、静かに歩いて行くことができますE#マリオはまっすぐに倒れるので、彼はに到達できないことに注意してください。

マリオがジャンプすることができ、実際に比較することによって非常に遠く前方に高いではなく。

S   E
== ==
 = =

マリオはギャップを飛び越えようとするかもしれませんが、彼は失敗し、まっすぐに落ちます。彼は終わりに達することができません。

マリオは、これらすべての例で目標を達成できます。

 E
 =
 =
 =
S=
==

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

S
=






=  E
====

これはコードゴルフなので、最少バイトが勝ちます!


2
落下の例では、「#マリオがまっすぐに倒れるので、彼はに到達できない」と言います。これを正しく表示している場合、彼はまっすぐに落ちません#か?また、ジャンプは最大で4スペース、最大で1スペースとして定義されていますか?
GuitarPicker

4
@GuitarPicker最初は同じように思っていましたが、よく見ると、の列の前にスペースの別の列があることがわかります#。2番目の質問について:私はOPではありませんが、あなたは正しいと思います。(それは私のソリューションで仮定したものです)
カールカストール

1
3番目の例(マリオのジャンプの高さを示す)ではE、地上レベルがマップの残りの部分から1つ右に伸びているため、右端の列には表示されません。
テイラーロペス

1
@ジョファン:Mario cannot walk through wall , and cannot fall past a floor, or jump past a ceiling
タイタス

1
@Titusマリオが澄んだ空気に飛び込み、着陸するために異なる階の選択肢を持つことを考えています-彼は下の階に行くことができますか?
ジョファン

回答:


11

スリップ38 27 25バイト

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

マリオがトラバースする必要のあるすべてのセルにスペースがあるように、入力を長方形にパディングする必要があります(潜在的にスペースでいっぱいの行で)。有効なパスを表す文字列(SEおよび=最後を除くすべてのウォークスルーを含む)を表示するか、パスが存在しない場合は何も出力しません。

ここでテストしてください。

説明

スリップは、Sp3000の 2Dパターンマッチング言語設計への挑戦でした。それは、正規表現の2D拡張のようなもので、左または右に曲がることが許可または要求されたときにエンジンのカーソルに指示を与えることができます。また、カーソルの進行を防ぐことができる便利な機能があり、1つの位置を2回連続して(異なるパターンで)一致させることができます。

スリップには正規表現の見回しに匹敵するものはありませんが、任意の位置を複数回移動できるため、条件をテストしてから戻ることができます。これを使用して、各ステップの後に地面タイルに移動することにより、地面にいるときのみジャンプするようにします。

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

ジャワ234 230 221 216 208 207 205 179のバイト

ほら、私はCとpythonを倒しましたか?私は人間の真の超越を達成しました!冗談はさておき、これは楽しいチャレンジでした。次の関数は、それぞれが同じ長さの列文字列の配列として入力を受け取ります。これが規則に反する場合は、お知らせください。マリオの実行が成功したことを意味する1と、マリオの実行に失敗したことを意味するその他の値が出力されます。

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

以下に、使用例と出力例を示す古いロジック(現在のバージョンに類似)を示します。さらに、ロジックを説明するいくつかのコメント

/**
 *
 * @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、あなたは私を手に入れましたが、与えられたテストケースは正しいです。問題は、各ステップでマリオが複数の方法を使用できるかどうかをopが特定していないことです。
Rohan Jhunjhunwala

追加の制約が指定されていない場合は、より一般的なバージョンを常に想定するため、そうなると想定しました。
カールカストール

@KarlKastorそうそう
Rohan Jhunjhunwala

7

Python、260 239 222 215 209 206バイト、

ideoneで試してください(テストケース付き)

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

次のように呼び出します: f([' S=', ' E='])

パッチノート:

現在、他のソリューションのいくつかと同様に、入力は「」で始まるcoloumn文字列の配列であると想定しています

古い入力フォームのラッパー: g=lambda x:f(map("".join,zip(*([" "*x.index("\n")]+x.split("\n")))))

また、マリオが彼の上のブロックを飛び越えることができるバグを修正しました。

説明なしのバージョン:

fマリオがに移動できるすべての方向に再帰的に自分自身を呼び出しますy,x。にTrue到達すると戻り、最後に戻る"E"ndまですべての関数呼び出しgを戻ります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

ジャンプが役に立たない場合は、地面に落ちます。else最後の前にを追加しreturnますか?
タイタス

5

カタツムリ41 37 29バイト

重複するパスを回避し、4バイトを節約するための助けをしてくれたfeersumに感謝します。

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

マリオがトラバースする必要のあるすべてのセルにスペースがあるように、入力を長方形に埋め込む必要があります(潜在的にスペースでいっぱいの行で)。

オンラインでお試しください!

説明

Snailsは、2Dパターンマッチング言語設計の課題に対するfeersumの参入でした。Slipと同様に正規表現にも似ていますが、主な違いは、a)これはアサーション(ルックアラウンド)をサポートし、b)これらのアサーションは別として、グリッド内のセルを2回走査することはできないことです。マリオが穴に落ちて飛び出す必要がある場合があるため、この問題は少し厄介です:

S E
= =
===

これらの違いは別として、2つの言語の構文もかなり異なります。

セルを2回移動できないという問題を回避するために、常に水平方向のステップと垂直方向のステップを交互に切り替えます。ただし、これは、棚を乗り越える前に転倒を処理する必要があることを意味します。そのため、技術的には滝はグラウンドタイルを通過しますが、オープンタイルの隣でのみ発生するようにします。

=\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バイト

「これは常に入力の左端の列に表示されます」で保存された20バイト
@RohanJhunjhunwalaの列ベースのシステムのおかげで23バイト保存

テストケースを使用して、ideoneで試してみてください...

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

使用法:

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

説明のないゴルフ:

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は、ランタイムエラーがあると言います
-TuxCrafting

6
待って、あなたは携帯ಠ_ಠにコーディングされている
TuxCrafting

4
ええ、私はラップトップにコーラをこぼしました:P
betseg

1
(公平性を確保するためだけにbetsegを意味するものではありません)@TùxCräftîñg:このソリューションは、文字列の配列(すでに「\ n」で分割)を取り、入力として長さと幅も持っているため、チャレンジに準拠していますかマップ(チャレンジの入力の一部ではありません)?
カールカストール


2

PHP、399 338 284 265 251バイト

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

コマンドライン引数として入力を予期し、Unixスタイルの改行とすべての行の末尾のスペースを使用し1、成功の場合は終了コード0、失敗の場合は終了コードを返します

機能の内訳

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
}

テスト(関数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
誰にでも:なぜこれを否定したのか教えてください。
タイタス

2

ルビー、 153 147バイト

申し訳ありませんが、Java ...仕事に最適なゴルフ以外の言語としてのあなたの場所が引き継がれています!

入力は列文字列のリストであり、Slip and Snailsソリューションが入力に空白の長方形を埋め込むことを要求する方法のスタイルで単一のスペースが先頭に追加されます。

オンラインでお試しください!

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 ....しかしuが「借り」、柱状の文字列の私の方法でした
ロハンJhunjhunwalaを

1
そうですね、すべてのクールな子供たちはすでにそれをやっていたのです。10バイトで、あなたのJavaに失うが、実際のソリューションは関係なく、短いかもしれない私の現在のコードを維持するために列に行を変更するために、「クイックフィックス」をやって、後から行ベースのソリューションを作るかもしれない
バリューインク

2

グライム、46バイト(非競合)

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

このチャレンジが投稿された後、Grimeを数回更新したため、この回答は受賞資格がありません。一部の変更は非常に新しいため、TIOに入れることができませんでしたが、一度行ったら、プログラムを試すことができます。いずれにせよ、私のリポジトリには、このコードを正しく処理するバージョンが含まれています

プログラムは1、マリオが目標を達成できる0かどうか、および達成できない場合に出力します。入力には、マリオが訪れる必要があるすべての場所にスペースを含める必要があります。一般的な入力については、次の57バイトのソリューションがあります。

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

説明

大まかな説明はA、最初の行で定義された非終端記号が、マリオが目標に到達できる入力の1×1のサブ長方形に一致することです。 Aは、リテラルE(マリオがすでにゴールに到達している)、または右列の別の一致への有効なマリオジャンプを含む2×nの長方形の左列にある1×1パターンとして定義されます。2行目は、開始文字も含む一致の数をカウントし、それを出力します。AAS

コードの内訳は次のとおりです。

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.

アイデアは\ {,-4}、左側の部分がマリオが上にジャンプ\ /*するスペースに一致し、右側の部分がスペーストラフに一致してから落下するというものです。私たちは、彼がA(ゴールに到達したいので)のマッチに着地することを要求し=ます。両方の列の下の垂直スタックは、列の高さが同じであることを単に保証するだけなので、それらを連結できます(これは、中央の単一スペースが行うことです)。上記の長方形に分割され、スペースが*sに置き換えられたサンプルのジャンプのASCIIアート図を次に示します。

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

2行目のオプションnは、最初の一致を見つける代わりに、すべての一致のカウントをトリガーします。一般的な解決策では、スペースは特別な入力外の文字であり、オプションbと、入力に入力外の文字が埋め込まれます。

これがすべて理にかなっていることを望みます!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.