마리오가이지도의 끝으로 갈 수 있습니까?


13

경로의 입력이 주어진 경우 마리오가 E시작부터으로 표시되는 끝에 도달 할 수 있는지 여부를 결정하는 프로그램을 작성하십시오 S.

경로는 다음과 같습니다.

S = E
=====

경로에서 다양한 기호와 그 의미는 다음과 같습니다.

  • =: 벽 / 바닥 / 천장. 마리오는 벽을 걷거나 바닥을 넘어서거나 천장을 뛰어 넘을 수 없습니다 (머리를 때릴 것입니다)
  • (공간) : 공기. 마리오는 이것을 뚫고 뛰어 넘을 수 있습니다.
  • S: 마리오가 시작되는 곳을 보여주는 것을 제외하고는 공기. 항상지면에서 입력의 가장 왼쪽 열에 나타납니다.
  • E: 마리오가 가고 싶은 곳을 보여주는 것을 제외하고는 공기. 이것은 항상지면에서 입력의 가장 오른쪽 열에 나타납니다.

입력은 Mario가 걸을 수있는 모든 장소에 공백이 있습니다.

마리오는 앞으로 나아갈 수만 있습니다. 이 예에서 Mario는 목표를 달성 할 수 없습니다

S
===

 ===
   E
====

그는 이것으로도 할 수 없다

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

그러나 그는 #최대 4 개의 셀까지 점프 할 수 있기 때문에 로 표시된 공간에 도달 할 수 있습니다 (입력에 나타나지 않음). 마리오는 초인간적입니다. 그의 초인 성의 또 다른 예로서 :

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

마리오는 E먼 거리를 넘어서 살아남아 침착하게 걸어 가서에 도착할 수 있습니다 E. #마리오는 똑바로 쓰러지므로 그는에 도달 할 수 없습니다 .

마리오는 정말 높이 뛰어 올 수 있지만 비교하면 그리 멀지는 않습니다.

S   E
== ==
 = =

마리오는 격차를 뛰어 넘 으려고하지만 실패하고 곧바로 넘어 질 것입니다. 그는 끝까지 도달 할 수 없습니다.

Mario는이 모든 예에서 목표에 도달 할 수 있습니다.

 E
 =
 =
 =
S=
==

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

S
=






=  E
====

이것은 코드 골프이므로 가장 적은 바이트가 이깁니다!


2
떨어지는 예에서, " #Mario가 똑바로 쓰러지기 때문에에 도달 할 수 없습니다."라고 언급합니다 . 내가 이것을 올바르게보고 있다면 그는 #? 또한 점프는 최대 4 개의 공백으로 정의되고 최대 1 개의 공백으로 정의됩니까?
GuitarPicker

4
@GuitarPicker 나는 처음에 생각했지만 자세히 보면 열 앞에 다른 공백 열이 있음을 알 수 있습니다 #. 두 번째 질문에 관해서는 : 나는 OP가 아니지만 당신이 옳은 것 같아요. (내 솔루션에서 가정 한
것임

1
세 번째 예 (Mario의 점프 높이를 나타내는) E는지면 레벨이 나머지 맵에서 오른쪽으로 1을 확장하므로 맨 오른쪽 열에 나타나지 않습니다.
Taylor Lopez

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

1
@Titus Mario가 맑은 공기로 뛰어 들어 착륙 할 다른 층을 선택하는 것에 대해 생각하고 있습니다. 더 낮은 층으로 갈 수 있습니까?
Joffan

답변:


11

슬립 , 38 27 25 바이트

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

모든 셀에 공백이있을 수 있도록 입력을 사각형으로 채울 필요가 있습니다. Mario는 가로 방향으로 채워질 수 있습니다. 인쇄 중 (포함하는 유효한 경로를 나타내는 문자열 S, E모든이 =의 마지막을 제외하고 걸었다 없음) 어떤 경로가 존재하지 않는 경우 또는 아무것도.

여기에서 테스트하십시오.

설명

Slip은 2D 패턴 일치 언어 디자인 과제 에 Sp3000을 도입 했습니다. 왼쪽 또는 오른쪽 회전이 허용되거나 필요할 때 엔진 커서에 지시를 줄 수있는 정규식의 2D 확장과 비슷합니다. 또한 커서가 전진하는 것을 방지 할 수있는 편리한 기능을 제공하여 단일 위치를 한 번에 두 번 일치시킬 수 있습니다 (패턴이 다름).

슬립은 정규 표현식에서 보이는 것과 비교할만한 것이 없지만 어떤 위치로 여러 번 이동할 수 있기 때문에 조건을 테스트 한 다음 돌아갈 수 있습니다. 우리는 각 단계 후에지면 타일로 이동하여지면에있을 때만 점프하도록하기 위해 이것을 사용합니다.

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와 파이썬을 이겼어? 필사자들 사이에서 진정한 초월을 얻었습니다! 모든 농담은 제쳐두고, 이것은 재미있는 도전이었습니다. 다음 함수는 각각 같은 길이의 열 문자열 배열로 입력을받습니다. 이것이 규칙에 위배되는 경우 알려주십시오. 성공한 마리오 실행을 의미하는 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, 당신은 나를 얻었지만 주어진 테스트 사례는 정확합니다. 문제는 작전이 마리오가 각 단계마다 갈 수있는 여러 가지 방법이 있는지 여부를 구체적으로 설명하지 않았다는 것입니다.
Rohan Jhunjhunwala

추가 구속 조건을 지정하지 않으면 항상 더 일반적인 버전을 사용하기 때문에 가능하다고 가정했습니다.
KarlKastor

@KarlKastor yeah ur right
Rohan Jhunjhunwala

7

파이썬 260 239 222 215 209 206 바이트

이데온에서 사용해보십시오 (테스트 케이스 포함)

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='])

패치 노트 :

이제 다른 솔루션과 마찬가지로 입력이 ""로 시작하는 열이 많은 문자열의 배열이라고 가정합니다.

기존 입력 양식의 래퍼 : g=lambda x:f(map("".join,zip(*([" "*x.index("\n")]+x.split("\n")))))

또한 마리오가 그 위의 블록을 뛰어 넘을 수있는 버그를 수정했습니다.

설명이 포함 된 ungolfed 버전 :

fMario가 이동할 수있는 모든 방향으로 반복해서 호출합니다 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하시겠습니까?
Titus

5

달팽이 , 41 37 29 바이트

겹치는 경로를 피하고 4 바이트를 절약하는 데 도움이되는 feersum 덕분에.

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

모든 셀에 공백이있을 수 있도록 입력을 사각형으로 채울 필요가 있습니다. Mario는 가로 방향으로 채워질 수 있습니다.

온라인으로 사용해보십시오!

설명

달팽이는 2D 패턴 일치 언어 디자인 과제에 대한 feersum의 입장 이었습니다 . 슬립과 마찬가지로 정규 표현식과 비슷하지만 가장 큰 차이점은 a)이 주장을 지원하고 (주변) b) 이러한 주장 외에 그리드의 모든 셀을 두 번 통과 할 수 없다는 것입니다. 마리오가 구멍에 빠지고 뛰어 내릴 필요가있는 경우가 있기 때문에이 문제는 약간 까다로워집니다.

S E
= =
===

이러한 차이점 외에도 두 언어의 구문도 상당히 다릅니다.

셀을 두 번 통과 할 수없는 문제를 피하기 위해 항상 수평 단계를 수직 단계로 바꿉니다. 그러나 이는 선반을 넘어 가기 전에 추락을 처리해야 함을 의미합니다. 따라서 폭포는 기술적으로 실제로지면 타일을 통과하지만 열린 공간 옆에서만 발생하도록 보장합니다.

=\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 바이트

@RohanJhunjhunwala의 열 기반 시스템 덕분에 "입력의 가장 왼쪽 열에 항상 나타납니다"로
23 바이트 절약

테스트 사례와 함께 아이디어로 시도해보십시오 ...

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
잠깐, 당신은 모바일 코딩 coding_ ಠ
TuxCrafting

4
Ye, 나는 내 노트북에 콜라를 쏟았다 : P
betseg

1
(로 평균을 사용하여야한다 betseg @ TùxCräftîñg 단지 공정성을 보장하기 위해) : 당신의 도전이 솔루션을 준수인가가 (이미 "N \"에 분할) 문자열의 배열을 또한 입력으로의 길이와 폭을 가지고 있기 때문에 지도 (챌린지 입력의 일부가 아님)?
KarlKastor


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

유닉스 스타일의 줄 바꿈과 모든 줄에 후행 공백이있는 명령 줄 인수로 입력을 예상하고 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
누구에게나 : 당신이 이것을 다운 보트 했는지 알려주시겠습니까 ?
Titus

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 .... 그러나 당신은 기둥 형 줄의 나의 방법을 "빌리기"
Rohan Jhunjhunwala

1
글쎄, 모든 멋진 아이들이 이미하고 있었다. 나중에 행 기반 솔루션을 작성하여 "빠른 수정"을 수행하여 현재 코드가 10 바이트 씩 Java에 손실되지 않도록 행으로 열을 수정하지만 실제 솔루션은 더 짧을 수 있습니다.
Value Ink

2

Grime, 46 바이트 (비경쟁)

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

이 챌린지가 게시 된 후 Grime을 여러 번 업데이트 했으므로이 답변을받을 수 없습니다. 일부 변경 사항이 너무 새로워 서 TIO로 가져올 수 없었지만 일단 변경 하면 프로그램을 사용해 볼 수 있습니다 . 어쨌든 내 저장소 에는이 코드를 올바르게 처리하는 버전이 포함되어 있습니다.

1Mario가 목표에 도달 할 수 있는지 여부에 따라 프로그램이 인쇄 됩니다 0. 입력에는 Mario가 방문해야하는 모든 위치에 공백이 있어야합니다. 일반적인 입력의 경우 다음 57 바이트 솔루션이 있습니다.

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

설명

높은 수준의 설명이 비단이다 A첫 줄에 정의가하는 일치하는 1 × 1 마리오가 목표에 도달 할 수있는 입력의 서브 사각형. A리터럴로 정의된다 E(마리오가 목표에 이미), 또는 같은 1 × 1 일부의 왼쪽 열에의 것을 패턴 2 × n 개의 직사각형의 또 다른 경기에 유효한 마리오 점프 포함하는 A오른쪽 열에에 있습니다. 두 번째 줄 A은 시작 문자를 포함하는 일치 항목의 수를 세어 S인쇄합니다.

코드는 다음과 같습니다.

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}왼쪽 의 부분이 Mario가 위로 점프 \ /*하는 공간과 일치하고 오른쪽 의 부분은 그가 넘어지는 공간과 일치한다는 것입니다. 우리는 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 | = | * |
                                 +---+---+

두 번째 줄 n에서이 옵션 은 첫 번째 일치 항목을 찾는 대신 모든 일치 항목을 계산합니다. 일반적인 솔루션에서 공백은 특수 입력 문자 일 수 있으며, 옵션으로 입력이 입력 문자 b로 채워집니다.

이 모든 것이 의미가 있기를 바랍니다!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.