얼음 미로 해결


19

아이스 미로는 Pokémon Gold와 Silver에서 데뷔 한 이후 Pokémon 게임에서 가장 좋아하는 주요 재료 중 하나였습니다 . 당신의 임무는 이러한 유형의 문제를 해결하는 프로그램을 만드는 것입니다.

얼음 미로는 주로 이름에서 알 수 있듯이 얼음으로 구성됩니다. 플레이어가 얼음 위에서 한 방향으로 움직이면 장애물과 충돌 할 때까지 그 방향으로 계속 움직입니다. 또한 자유롭게 이동할 수있는 토양이 있으며, 플레이어가 그 위로 이동하는 것을 막을 수 있습니다. 마지막 장애물은 돌입니다. 스톤은 플레이어와 같은 공간을 차지할 수 없으며 플레이어가 이동을 시도하면 이동을 멈출 수 있습니다.

3 가지 유형의 바닥 (아이스, 토양 및 석재) 각각에 대해 3 개의 고유 한 값을 포함하는 목록 목록 또는 줄 바꾸기로 구분 된 문자열과 같은 2 차원 값 컨테이너가 제공됩니다. 미로의 시작과 목표 좌표를 나타내는 두 쌍 (또는 다른 동등한 두 값 컨테이너)도 받게됩니다. 이들은 0 또는 하나의 색인 일 수 있습니다.

수행 할 때 플레이어가 끝에 도달하게하는 동작 목록 (N, E, S, W에 4 개의 고유 한 값이있는 4 개의 고유 한 값)을 출력해야합니다.

입력은 항상 미로 주위에 돌 주변이 닫혀 있으므로 플레이어가 미로를 빠져 나갈 염려가 없습니다.

이것은 이므로 가장 적은 바이트가 이깁니다.

테스트 사례

여기는 .얼음 ~을 나타내고 토양 O을 나타내며 돌을 나타냅니다. 좌표는 1 인덱스입니다. 솔루션의 각 문자는 해당 문자로 시작하는 방향을 나타냅니다 (예 N: 북쪽)


입력

OOOOO
OO.OO
O...O
OOOOO

Start : 3,3
End   : 3,2

산출

N

입력

OOOOOOOOOOOOOOOOO
O........O.....OO
O...O..........OO
O.........O....OO
O.O............OO
OO.......O.....OO
O.............OOO
O......O.......~O
O..O...........~O
O.............OOO
O.......O......OO
O.....O...O....OO
O..............OO
OOOOOOOOOOOOOO~~O
OOOOOOOOOOOOOOOOO

Start : 15,12
End   : 16,8

산출

N,W,N,E,N,E,S,W,N,W,S,E,S,E,N,E,N

입력

OOOOOOOOOOOOOOOO
O~~~~~OOOOO~~~~O
O~~O~OOOOOOO~~OO
O...O..........O
O........O.....O
O..............O
OO.............O
O.............OO
O....~....O....O
O..............O
O..............O
OOOOOOOOOOOOOOOO

Start : 2,2
End   : 14,3

산출

E,S,S,W,N,E,N

입력

OOOOOOOOOOOOOOOOOOO
O~~~~~~~OOOOOOOOOOO
O~~~~...OOOOOOOOOOO
OO~O~..OOOOOOOOOOOO
O..OO.............O
O..............O..O
O....O............O
O.O............~..O
O........OOOO.....O
O.......OOOOO.....O
O.......O~~~O.....O
O.......~~~~~.....O
O.......~~~~~.....O
O..........O......O
O..O..~...........O
O...............O.O
O.....O...........O
O.................O
OOOOOOOOOOOOOOOOOOO

Start : 2,2
End   : 11,11

산출

E,E,E,E,E,S,S,E,N,W,S,E,N,N,N

입력에 항상 하나 이상의 유효한 솔루션이 있습니까?
Pavel

@Pavel 당신은 그렇게 생각할 수 있습니다.
밀 마법사

테스트 사례 (행, 열) 또는 (열, 행)입니까? 1 또는 0 색인이 생성 되었습니까? 보드 가장자리는 벽으로 간주됩니까?
MildlyMilquetoast


2
@busukxuan 당신은 미로에 영구적으로 갇힐 수 있습니다 (테스트 사례 1 참조)
밀 마법사

답변:


4

Mathematica, 247 바이트

(p=x#[[##&@@x]];m={c,v}Switch[p[c+v],0,m[c+v,v],1,c+v,_,c];g=Cases[Array[List,Dimensions@#],c_/;p@c<2,{2}];a=cm[c,#]&/@{{1,0},{-1,0},{0,1},{0,-1}};e=Flatten[Table[#->c,{c,a@#}]&/@g,1];Normalize/@Differences@FindPath[Graph[e],#2,#3][[1]])&

줄 바꿈으로 :

(
p=x#[[##&@@x]];
m={c,v}Switch[p[c+v],0,m[c+v,v],1,c+v,_,c];
g=Cases[Array[List,Dimensions@#],c_/;p@c<2,{2}];
a=cm[c,#]&/@{{1,0},{-1,0},{0,1},{0,-1}};
e=Flatten[Table[#->c,{c,a@#}]&/@g,1];
Normalize/@Differences@FindPath[Graph[e],#2,#3][[1]]
)&

필자의 즉각적인 아이디어는 합법적 인 움직임에 해당하는 모서리가있는 그래프에서 얼음과 토양 위치를 노드로 나타내는 것 FindPath입니다. 합법적 인 움직임을 결정하는 것이 쉬운 부분이라고 생각할 수도 있고 해결책을 찾는 것이 어려운 부분이라고 생각할 수도 있습니다. 저에게는 반대였습니다. 모서리를 계산하는 방법에 대한 제안을 엽니 다.

첫 번째 주장 #0얼음, 1토양, 2돌을 나타내는 2D 배열 입니다.

두 번째 인수 #2와 세 번째 인수 #3는 각각 시작 및 끝점 형식 {row,column}입니다.

3 바이트 점용 문자 U+F4A1표현은 \[Function].

설명

p=x#[[##&@@x]];

양식 및 출력 p목록을 취하는 함수 를 정의합니다 . 즉, 그 좌표에서의 얼음 / 토양 / 돌 값.x{row,column}#[[row,column]]

m={c,v}Switch[p[c+v],0,m[c+v,v],1,c+v,_,c]

m시작 위치 c와 방향 벡터 를 취하고 v끝을 재귀 적으로 결정 하는 함수 를 정의합니다 . 경우 c+v얼음이, 우리는 그래서 반환, 그 시점에서 슬라이딩 계속 m[c+v,v]. c+v흙 이라면 , 우리는 이사 c+v하고 멈 춥니 다. 그렇지 않으면 ( c+v돌이 있거나 경계를 벗어난 경우) 움직이지 않습니다. 이것은 얼음 또는 토양 위치에서만 호출되도록되어 있습니다.

g=Cases[Array[List,Dimensions@#],c_/;p@c<2,{2}];

g얼음 및 토양 위치 목록 을 정의합니다 ( p보다 작은 값 2).

a=cm[c,#]&/@{{1,0},{-1,0},{0,1},{0,-1}}; 

함수 정의 a시작 위치 얻어 c및 복귀 이동의 결과 {1,0}, {-1,0}, {0,1}{0,-1}방향. 중복이있을 수 있습니다. 다시 말하지만 이것은 c얼음이나 토양에 해당 한다고 가정합니다 .

e=Flatten[Table[#->c,{c,a@#}]&/@g,1];

e법적 이동을 나타내는 방향 모서리 목록 을 정의합니다 . 각 위치 #에서 g, 에지의 계산 테이블 #->cc하여 a@#. 그런 다음 각 위치에 대한 하위 목록으로 끝나 #므로 첫 번째 수준을 평평하게 만듭니다. 루프와 가장자리가 여러 개있을 수 있습니다.

Normalize/@Differences@FindPath[Graph[e],#2,#3][[1]]

Graph[e]노드가 합법적 인 위치 (얼음 또는 토양)이고 가장자리가 합법적 인 움직임을 나타냅니다 (돌에 부딪쳐 움직일 수 없음). 우리는 다음 사용 FindPath에서 경로 찾기 #2#3노드의 목록으로 표시합니다. FindPath하나 이상의 경로를 찾기 위해 추가 인수를 취할 수 있으므로 결과는 실제로 단일 경로를 포함하는 목록이되므로을 사용하여 첫 번째 요소를 사용 [[1]]합니다. 그런 다음 Differences좌표와 Normalize그 연속 을 가져옵니다 . 따라서 위는 {-1,0}, 아래는 {1,0}, 오른쪽은 {0,1}왼쪽입니다 {0,-1}.

테스트 사례

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오


4

자바 스크립트 (ES6) 180 183

(m,[x,y],[t,u],o=~m.search`
`,s=[[x-y*o,[]]],k=[])=>eval("for(i=0;[p,l]=s[i++],k[p]=t-u*o-p;)[-1,o,1,-o].map(d=>k[q=(M=p=>+m[p+=d]?m[p]<8?M(p):p:p-d)(p)]||s.push([q,[...l,d]]));l")

이 관련 문제 를 해결하기 위해 BFS 사용

입력
미로지도는 토양을 위해 O또는 0돌을 사용 하거나 8얼음을 위해 8보다 작은 숫자 (0이 아닌 숫자)를 사용하는 여러 줄 문자열 7입니다.
시작 및 종료 위치는 0을 기준으로합니다.

출력
-1은 W, 1은 E, -1보다 작은 음수 , 1 N보다 큰 양수 는 오프셋 목록입니다.S

덜 골프

(m,[x,y],[t,u])=>{
  o=~m.search`\n`
  s=[[x-y*o,[]]]
  k=[]
  for(i=0; [p,l]=s[i++], k[p]=1, t-u*o != p;)
  {
    [-1,o,1,-o].map(d=>(
      M=p=>+m[p+=d] ? m[p]<8 ? M(p) : p : p-d,
      q=M(p),
      k[q]||s.push([q,[...l,d]])
    ))
  }
  return l
}

테스트

Solve=
(m,[x,y],[t,u],o=~m.search`
`,s=[[x-y*o,[]]],k=[])=>eval("for(i=0;[p,l]=s[i++],k[p]=t-u*o-p;)[-1,o,1,-o].map(d=>k[q=(M=p=>+m[p+=d]?m[p]<8?M(p):p:p-d)(p)]||s.push([q,[...l,d]]));l")

function Go(maze) {
  var map = maze.textContent;
  var [sx,sy, dx,dy] = map.match(/\d+/g)
  --sx, --sy // zero based
  --dx, --dy // zero based
  map = map.split('\n').slice(1).join('\n') // remove first line
  var result = Solve(map.replace(/\./g, 7).replace(/~/g, 8), [sx,sy], [dx,dy])
  S.textContent = result
  Animate(maze, map, result, sx, sy)
}

function Display(maze, map, pos) {
  var row0 = maze.textContent.split('\n')[0]
  map = [...map]
  map[pos] = '☻'
  maze.textContent = row0+'\n'+map.join('')
}

function Animate(maze, map, moves, x, y) {
  console.log('A',moves)
  var offset = map.search('\n')+1
  var curPos = x + offset * y
  var curMove = 0
  var step = _ => {
    Display(maze, map, curPos)
    if (curMove < moves.length) 
    {
      curPos += moves[curMove]
      if (map[curPos] == 'O')
      {
        curPos -= moves[curMove]
        ++curMove
      }  
      else 
      {
        if (map[curPos] == '~') {
          ++curMove
        }
      }
      setTimeout(step, 100)
    }
    else
      setTimeout(_=>Display(maze,map,-1),500)
  }
  step()
}
td { 
  border: 1px solid #888;
}
Select maze<pre id=S></pre>
<table cellspacing=5><tr>
<td valign=top><input type=radio name=R onclick='Go(M1)'><br>
<pre id=M1>3,3 to 3,2  
OOOOO
OO.OO
O...O
OOOOO</pre></td>
<td valign=top><input type=radio name=R onclick='Go(M2)'><br>
<pre id=M2>15,12 to 16,8
OOOOOOOOOOOOOOOOO
O........O.....OO
O...O..........OO
O.........O....OO
O.O............OO
OO.......O.....OO
O.............OOO
O......O.......~O
O..O...........~O
O.............OOO
O.......O......OO
O.....O...O....OO
O..............OO
OOOOOOOOOOOOOO~~O
OOOOOOOOOOOOOOOOO</pre></td>
<td valign=top><input type=radio name=R onclick='Go(M3)'><br>
<pre id=M3>2,2 to 14,3
OOOOOOOOOOOOOOOO
O~~~~~OOOOO~~~~O
O~~O~OOOOOOO~~OO
O...O..........O
O........O.....O
O..............O
OO.............O
O.............OO
O....~....O....O
O..............O
O..............O
OOOOOOOOOOOOOOOO</pre></td>
<td valign=top><input type=radio name=R onclick='Go(M4)'><br>
<pre id=M4>2,2 to 11,11
OOOOOOOOOOOOOOOOOOO
O~~~~~~~OOOOOOOOOOO
O~~~~...OOOOOOOOOOO
OO~O~..OOOOOOOOOOOO
O..OO.............O
O..............O..O
O....O............O
O.O............~..O
O........OOOO.....O
O.......OOOOO.....O
O.......O~~~O.....O
O.......~~~~~.....O
O.......~~~~~.....O
O..........O......O
O..O..~...........O
O...............O.O
O.....O...........O
O.................O
OOOOOOOOOOOOOOOOOOO</pre></td>
</tr></table>

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