태그 보관물: path-finding

path-finding

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

경로의 입력이 주어진 경우 마리오가 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
====

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



답변

슬립 , 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.

답변

자바 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=");

    }

}

답변

파이썬 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

답변

달팽이 , 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.

답변

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
}

답변

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

답변

루비, 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]}}