氷の迷路を解く


19

氷の迷路は、ポケモンゴールドとシルバーでデビューして以来、ポケモンゲームの主なお気に入りの1つです。あなたの仕事は、これらのタイプの問題を解決するプログラムを作成することです。

名前が示すように、氷の迷路は主に氷で構成されています。プレイヤーが氷上である方向に移動すると、障害物と衝突するまでその方向に移動し続けます。自由に移動できる土壌もあり、プレイヤーが移動するのを止めます。最後の障害は石です。ストーンはプレイヤーと同じスペースを占有できず、プレイヤーがそこに移動しようとすると、移動する前に停止します。

リストのリストや改行で区切られた文字列など、3種類のフローリング(氷、土、石)ごとに3つの異なる値を含む、値の2次元コンテナを受け取ります。また、迷路内の開始座標と目標座標を示す2つのペア(または他の同等の2つの値コンテナー)を受け取ります。これらはゼロまたは1つのインデックスが付けられます。

実行時にプレイヤーが最後に到達するようにする動きのリスト(N、E、S、Wへの全単射で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

入力には常に少なくとも1つの有効なソリューションがありますか?
パベル

@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番目の引数#2と3番目の引数#3は、それぞれ形式の開始点と終了点{row,column}です。

はをU+F4A1表す3バイトの私用文字\[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、エッジの表計算#->c各々のためcには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

JavaScriptの(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未満のゼロ以外の数字を使用した複数行の文字列です(7見栄えが良い)。
開始位置と終了位置はゼロベースです。

出力
オフセットのリスト。-1はW1、1は-1、-1はE負、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.