역 화살표 미로 해결


14

이것은 "화살표 미로"입니다 :

  v      < 
>     v    
      >  ^ 
>         v
^ <       *

*마크 당신이 완료됩니다 자리. 당신의 목표는 미로 가 시작 되는 곳을 찾는 것입니다 (따라서 역 미로). 이 경우 >두 번째 줄 에서 첫 번째 입니다.

  v------< 
S-+---v  | 
  |   >--^ 
>-+-------v
^ <       *

모든 화살표를 사용해야합니다. 또한 줄이 같은 길이의 공백으로 채워질 것이라고 가정 할 수 있습니다.

프로그램은 미로를 합리적인 방법으로 (파일, 메시지 상자 등에서) 입력 해야 하지만 미로 완전히 손상되지 않아야합니다 . 예를 들어 쉼표로 구분 된 행을 입력 할 수 없습니다. 입력은 정확히 미로 여야합니다.

합리적인 방법으로 미로의 시작을 출력해야합니다. 예를 들어

  • 시작의 좌표를 출력
  • 시작 화살표로 교체하여 전체 미로를 출력 S
  • 시작 화살표를 제외한 모든 화살표와 함께 전체 미로를 출력하십시오 (공백은 그대로!)
  • 기타

출력으로 어떤 화살표가 시작 화살표인지 알 수 있다면 괜찮습니다. 예를 들어,

"0"
"2"

줄 바꿈과 따옴표에 관계없이 시작 위치를 여전히 알 수 있기 때문에 괜찮습니다.

이것은 이므로 바이트 단위의 가장 짧은 코드가 승리합니다.


각 화살표에 다른 화살표가 하나만 있다고 가정하는 것이 합리적입니까? 여러 개의 시작점이있을 수있는 인스턴스가 없을까요?
Danny

"미로의 시작"은 서로 화살표를 한 번 방문하는 화살표입니까? 다시 말해 danny의 질문 + 가정에는 루프가 없습니다.
shiona

3
"쉼표로 구분 된 줄을 입력 할 수 없습니다. 입력은 정확히 미로 여야합니다." "정확히 미로는"이미 때문에 이것은 불필요한 제한 것 같다 사실상의 행 사이에 줄 바꿈으로 구분. 한 구분 기호를 다른 구분 기호보다 우선하는 이유는 무엇입니까?
Jonathan Van Matre 14

1
@Doorknob 이론적으로 "구분 기호"로 전체 압축 솔루션을 인코딩 할 수 있기 때문에 합리적입니다. 그러나 제한으로 인해 특정 언어에 대한 특정 언어 적 편견이 생길 것으로 생각됩니다. 규칙이 " 선택한 문자로 입력 행을 구분할 수 있습니다 . 모든 행은 동일한 문자 로 구분해야합니다 "? 상한선은 프로그램 작동 해야하는 도메인을 설정하기 때문에 유용하다고 생각합니다 .
Jonathan Van Matre

1
@Peter 그것은 단지 예를 들어에서 >v^에서 >가 아닌를 가리키는 것을 의미 v합니다 ^. 오늘 컴퓨터에 집으로 돌아 오면 더 많은 내용을 편집하겠습니다.
Doorknob

답변:


4

GolfScript, 55 바이트

:&,,{&=42>},.{.&="><^v"?[1-1&n?~.~)]=:d;{d+.&=32=}do}%-

온라인 데모

모든 입력 줄이 같은 길이의 공백으로 채워지고 줄 바꾸기로 구분되었다고 가정합니다. 입력 문자열의 시작 부분에서 시작 화살표의 바이트 오프셋을 출력합니다 (예 : 12챌린지의 미로 예).

특히,이 프로그램은 화살표를 가리키는 다른 화살표가없는 모든 화살표의 바이트 오프셋을 찾습니다 (모든 화살표가 화살표 또는 목표를 가리키고 있다고 가정하면, 이것이 사실이 아닌 경우 이상한 동작이 발생할 수 있음). 기본적으로 이러한 화살표가 여러 개인 경우 (사양에 따라 유효한 입력에서는 가능하지 않아야 함) 오프셋은 단순히 출력에 연결됩니다. 원하는 경우 n*프로그램에 추가 하여 개행 문자로 구분할 수 있습니다.

주석이 포함 된 골프 골드 버전 :

:&                     # save a copy of the input string in the variable "&"
,, { &= 42> },         # make a list of the byte offsets of all arrows 
.                      # duplicate the list and apply the following loop to it:
{
  .                    # make a copy of the original offset...
  &=                   # ...and get the corresponding character in the input
  "><^v" ?             # map the arrow character to integers 0 to 3, and...
  [ 1 -1 &n?~ .~) ]=   # ...map these to +1, -1, -len-1 or +len+1, where len is the...
  :d;                  # ...length of the first input line, and save result as "d"
  { d+ . &= 32= } do   # add d to the byte offset until another non-space is found
} %
-                      # subtract the resulting list of target offsets from the
                       # original list of arrow offsets; this should leave exactly
                       # one offset, which is left on the stack for output

1
인라인하면 3자를 저장할 수 있습니다 w.
Howard

@Howard : 허, 그래서 할 수 있습니다. 감사! 그러나 여분의 공간이 필요하지 않도록 이름 z을 바꾸어야했습니다 &. OTOH ?~.~)는 꽤 좋은 스마일리를 만듭니다. :-)
Ilmari Karonen

5

GolfScript ( 101 100 바이트)

n/:g,,{:&g=:r,,{&1$r='^v<>*'?70429 3base 2/=++}/}%{,4=},.{2<}%:&\{2/~\{[~2$~@+(@@+(\]&1$?)!}do\;}%^`

출력은 [[x y]]좌표가 모두 0을 기준으로하는 형식입니다.

온라인 데모

처리는 두 단계로 이루어집니다. 첫 번째 단계는 미로를 [x y dx dy]튜플 배열로 바꿉니다 . 두 번째 단계는 각 화살표 / 별표를 가리키는 화살표 / 별표에 매핑합니다. (별표는 자신을 가리키는 것으로 간주됩니다). 문제의 정의에 따르면이지도의 결과에 포함되지 않은 화살표가 정확히 하나이며 이것이 해결책입니다.


당신이 이것을 게시하는 동안 나는 단지 내 대답을 붙여 넣고있었습니다. 우리는 같은 생각을 가지고 있지만, 당신은 그것을 성공적으로 골프를 쳤다. 좋은 것!
Vereos

@PeterTaylor 나는 그것이 처리하는 볼 수 없습니다 통해 지점 코멘트에서 언급 올바르게 경우.
Howard

@Howard, 나는 그 사건이 무엇인지 전혀 모른다. 설명을 요청합니다.
피터 테일러

입력 및 출력의 예를 친절하게 게시 하시겠습니까?
DavidC

@DavidCarraher, 온라인 데모를 참조하십시오. stdin을 통한 ;'STUFF'공급 STUFF을 시뮬레이션합니다 .
피터 테일러

2

매스 매 티카 491 323

주석이 달린 골퍼

절차는 마무리 ( "*")에서 시작하여 시작점에 도달 할 때까지 화살표를 찾습니다.

기능, f [maze].

(* positions of the arrowheads *)
aHeads[a_]:=Position[m,#]&/@{"^","v",">","<"}

(* position of the final labyrinth exit*)
final[a_]:=Position[a,"*"][[1]];


(* find arrowheads that point to the current location at {r,c} *)
aboveMe[{r_,c_},a_]:=Cases[aHeads[a][[2]],{r1_,c}/;r1<r]
belowMe[{r_,c_},a_]:=Cases[aHeads[a][[1]],{r1_,c}/;r1>r]
rightOfMe[{r_,c_},a_]:=Cases[aHeads[a][[4]],{r,c1_}/;c1>c]
leftOfMe[{r_,c_},a_]:=Cases[aHeads[a][[3]],{r,c1_}/;c1<c]

(*find the precursor arrowhead*)
precursor[{loc_,a_,list_:{}}]:=

(* end the search when the precursor has already been traversed or when there is no precursor *)
Which[MemberQ[list,loc],list,
loc=={},list,True,


(* otherwise find the next precursor *)

전구체 [{Flatten [{aboveMe [loc, a], 아래 Me [loc, a], rightOfMe [loc, a], leftOfMe [loc, a]}, 2], a, Prepend [list, loc]}]]

(* return the path through the maze from start to finish *)
f[maze_]:= precursor[{final[maze[[1]]],maze[[1]]}]

골프

f@z_:=Module[{p,h,m=z[[1]]},h@a_:=Position[a,#]&/@{"^","v",">","<","*"};
  p[{v_,a_,j_:{}}]:=Module[{r,c,x=Cases},{r,c}=v;
  Which[MemberQ[j,v],j,v=={},j,True,
  p[{Flatten[{x[h[a][[2]],{r1_,c}/;r1<r],x[h[a][[1]],{r1_,c}/;r1>r],
  x[h[a][[4]],{r,c1_}/;c1>c],x[h[a][[3]],{r,c1_}/;c1<c]},2],a,Prepend[j,v]}]]];
  p[{Position[m,"*"][[1]],m}]]

미로. 정렬 된 각 쌍에는 셀의 행과 열이 포함됩니다. 예를 들어 {2, 3}은 2 행 3 열의 셀을 나타냅니다.

maze=Grid[Normal@ SparseArray[{{5, 5} -> "*",{1, 2} -> "v", {1, 5} -> "<",{2, 1} -> ">",
   {2, 3} -> "v",{3, 3} -> ">", {3, 5} -> "^",{4, 1} -> ">", {4, 5} -> "v",{5, 1} -> "^", 
   {5, 2} -> "<",{_, _} -> " "}]]

미로


입력

f[maze]

출력 : 시작부터 끝까지의 경로입니다.

{{2, 1}, {2, 3}, {3, 3}, {3, 5}, {1, 5}, {1, 2}, {5, 2}, {5, 1}, { 4, 1}, {4, 5}, {5, 5}}


입력 형식이 잘못되었습니다- "입력은 정확히 미로 여야합니다".
Doorknob

입력은 이제 미로 자체입니다.
DavidC

코드를 따르지 않았지만 "입력은 이제 미로입니다"라는 문제 를 해결하는 방법 이 재미 있습니다! +1 ... "STDIN은 보편적"이라는 신자들의 수가 놀랍습니다.
Dr. belisarius

입력 문제에 대한 해결책을 주셔서 감사합니다.
DavidC

1

나는 이것을 해결하는 좋은 방법을 찾았다 고 생각하지만, 골프를 타면서 빨랐다. 나는 이것이 더 짧을 수 있다고 생각합니다. 그래서 다른 사람들이 그것을 잘 발견 할 수 있도록 내 아이디어를 설명 할 것입니다.

모든 화살표를 사용해야하는 경우 모든 화살표는 하나를 제외한 다른 화살표로 표시됩니다. 이것이 바로 솔루션입니다.

즉, 실제로 미로를 뒤로 재생할 필요는 없지만 왼쪽 상단부터 시작하여 가장 가까운 화살표를 확인하면됩니다. 이것은 더 큰 미로에 대한 진정한 고통의 보호기입니다 (네 방향을 모두 확인할 필요는 없기 때문에 하나만).

내 해결책은 다음과 같습니다.

PHP, 622 바이트

$h=fopen("a.txt","r");$b=0;while(($z=fgets($h))!==false){$l[$b]=str_split($z,1);$b++;}$v=array("^","<","v",">");$s=array();for($i=0;$i<count($l);$i++){for($j=0;$j<count($l[0]);$j++){if(in_array($l[$i][$j],$v)){switch($l[$i][$j]){case"^":$c=$i-1;while($l[$c][$j]==" ")$c--;$s[]=$c.",".$j;break;case"v":$c=$i+1;while($l[$c][$j]==" ")$c++;$s[]=$c.",".$j;break;case"<":$c=$j-1;while($l[$i][$c]==" ")$c--;$s[]=$i.",".$c;break;case">":$c=$j+1;while($l[$i][$c]==" ")$c++;$s[]=$i.",".$c;break;}}}}for($i=0;$i<count($l);$i++){for($j=0;$j<count($l[0]);$j++){if(in_array($l[$i][$j],$v)){if(!in_array($i.",".$j,$s)){echo$i.",".$j;}}}}

언 골프 드 :

$h=fopen("a.txt","r");
$b=0;
while(($z=fgets($h))!==false) {
    $l[$b]=str_split($z,1);
    $b++;
}
//Input ends here
$v = array("^","<","v",">");
$s = array();
//Here i check every arrow, and save every pointed one in $s
for($i=0;$i<count($l);$i++){
    for($j=0;$j<count($l[0]);$j++){
        if(in_array($l[$i][$j],$v)){
            switch($l[$i][$j]) {
                case "^":
                    $c=$i-1;
                    while ($l[$c][$j]==" ")
                        $c--;
                    $s[]=$c.",".$j;
                    break;
                case "v":
                    $c=$i+1;
                    while ($l[$c][$j]==" ")
                        $c++;
                    $s[]=$c.",".$j;
                    break;
                case "<":
                    $c=$j-1;
                    while ($l[$i][$c]==" ")
                        $c--;
                    $s[]=$i.",".$c;
                    break;
                case">":
                    $c=$j+1;
                    while ($l[$i][$c]==" ")
                        $c++;
                    $s[]=$i.",".$c;
                    break;
            }
        }
    }
}
//I check if the arrow is in $s. If not, we have a solution.
for($i=0;$i<count($l);$i++){
    for($j=0;$j<count($l[0]);$j++){
        if (in_array($l[$i][$j],$v)){
            if (!in_array($i.",".$j,$s)){
                echo$i.",".$j;
            }
        }
    }
}

1

PHP -492 바이트

$r=split("\n",$m);$h=count($r);foreach($r as &$k)$k=str_split($k);$l=count($r[0]);$e=strpos($m,"*")+1-$h;$a=$x=$e%$l;$b=$y=floor(($e-$x)/$l);do{$c=0;for(;--$a>=0;){if($r[$b][$a]==">"){$x=$a;$c++;}if($r[$b][$a]!=" ")break;}$a=$x;for(;--$b>=0;){if($r[$b][$a]=="v"){$y=$b;$c++;}if($r[$b][$a]!=" ")break;}$b=$y;for(;++$a<$l;){if($r[$b][$a]=="<"){$x=$a;$c++;}if($r[$b][$a]!=" ")break;}$a=$x;for(;++$b<$h;){if($r[$b][$a]=="^"){$y=$b;$c++;}if($r[$b][$a]!=" ")break;}$b=$y;}while($c>0);echo "$x-$y";

이 솔루션은 맵이 로컬 변수에서 찾을 수 있다고 가정합니다 $m. 전달하는 가장 짧은 방법은 via $_GET: $m=$_GET['m'];14 바이트입니다. 읽기 쉬운 명확성을 위해 변수에 맵이있는 ungolfed 버전이 아래에 제공됩니다.

$m=<<<EOT
  v      < 
>     v    
      >  ^ 
>         v
^ <       * 
EOT;

$r=split("\n",$m);
$h=count($r);
foreach($r as &$k)
    $k=str_split($k);
$l=count($r[0]);

$e=strpos($m,"*")+1-$h;

$a=$x=$e%$l;
$b=$y=floor(($e-$x)/$l);
do{
$c=0;
for(;--$a>=0;)
    {
        if($r[$b][$a]==">"){$x=$a;$c++;}
        if($r[$b][$a]!=" ")break;
    }
$a=$x;
for(;--$b>=0;)
    {
        if($r[$b][$a]=="v")
            {
                $y=$b;
                $c++;
            }
        if($r[$b][$a]!=" ")break;

    }
$b=$y;
for(;++$a<$l;)
    {
        if($r[$b][$a]=="<")
            {
                $x=$a;
                $c++;
            }
        if($r[$b][$a]!=" ")break;
    }
$a=$x;
for(;++$b<$h;)
    {
        if($r[$b][$a]=="^")
            {
                $y=$b;
                $c++;
            }
        if($r[$b][$a]!=" ")break;
    }
$b=$y;
}while($c>0);
echo "$x-$y";

1

K, 281 277 258

{{$[&/x in*:'{{~"*"=x 1}{(s;k . s;k;s:*1_w@&(k ./:w:{{x@&x in y}[(*:'{(x[1]@x 0;x 1)}\[x;(z;y)]);i]}[(h!b,b,a,a:#k:x 2)m;(h!(0 1+;0 -1+;1 0+;-1 0+))m:x 1;x 0])in"*",h:"><v^")}\(x;y;z;x)}[*x;y .*x;y];*x;.z.s[1_x]y]}[i@&~(x ./:i::,/(!#x),/:\:!b::#*x)in" *";x]}

여기 초기의 언 골프 버전이 있습니다.

solve:{[x]
    //j - indices of all possible starting points
    //i - every index
    j::i@&~(x ./:i::,/(!a:#x),/:\:!b:#*x) in " *";

    h::">v<^";

    //d - dictionary mapping each directional character to
    //    increment/decerement it needs to apply to the x/y axis
    d::h!((::;1+);(1+;::);(::;-1+);(-1+;::));

    //e - dictionary mapping each directional character to
    //    the maximum number of moves it should make in a 
    //    given direction
    e::h!b,a,b,a;

    //f - function to produce the indices of each point that is 
    //    passed once we move in a certain direction from a 
    //    certain index
    f::{{x@&x in y}[(last'{(x[0];x[0]@'x 1)}\[x;(y;z)]);i]};

    //g - function that, given a starting and a direction,
    //    moves in that direction until hitting another directional
    //    character. It then moves in the new direction etc. until
    //    it reaches the end point -- *
    g::{[x;y;z]
        {[x]
            q:x 0;m:x 1; k:x 2;
            w:f[e m;d m;q];
            s:*1_w@&(k ./:w)in h,"*";
            m:k . s;
            (s;m;k;s)}\[{~"*"=x 1};(x;y;z;x)]};

    // recursive function that starts at the first possible starting point
    // and plots its way to the end. If all other potential starting points
    // have been touched in this path, then this is the correct starting point.
    // else, recursively call the function with the next possible starting point
    :{$[min "b"$j in last'g[*x;y . *x;y];*x;.z.s[1_x;y]]}[j;x]
  }

x y0 부터 시작 하는 인덱스와 같이 시작점을 반환합니다 .

k)maze
"  v      < "
">     v    "
"      >  ^ "
">         v"
"^ <       *"
k)solve maze
1 0

1

파이썬 422

with open("m.txt","r") as f:m=f.read().split("\n")
p=[(v.find("*"),p) for p,v in enumerate(m) if "*" in v][0]
g=[]
def f(a):
    x,y=b,c=a
    for p,i in enumerate((lambda x:[l[x] for l in m])(x)):
        if i in "^>v<" and((p<y and i=="v")or(p>y and i=="^")):return b,p
    for p,i in enumerate(m[y]):
        if i in "^>v<" and((p<x and i==">")or(p>x and i=="<")):return p,c
while True:
    z=f(p)
    if z in g:break
    else:g.append(z);p=z
print p

입력은이라는 파일에 m.txt있습니다. 출력은 (x, y)되지만 마지막 print 문을로 변경하면 print g출력은 [(x, y), (x, y), ...]끝에서 시작까지 모든 단계와 같은 목록이 됩니다.

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