using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("5");
WillReturn.Add("1 3");
WillReturn.Add("3 5");
WillReturn.Add("....#");
WillReturn.Add("...#.");
WillReturn.Add(".....");
WillReturn.Add(".#...");
WillReturn.Add("#....");
//3
}
else if (InputPattern == "Input2") {
WillReturn.Add("4");
WillReturn.Add("3 2");
WillReturn.Add("4 2");
WillReturn.Add("....");
WillReturn.Add("....");
WillReturn.Add("....");
WillReturn.Add("....");
//-1
}
else if (InputPattern == "Input3") {
WillReturn.Add("18");
WillReturn.Add("18 1");
WillReturn.Add("1 18");
WillReturn.Add("..................");
WillReturn.Add(".####.............");
WillReturn.Add(".#..#..####.......");
WillReturn.Add(".####..#..#..####.");
WillReturn.Add(".#..#..###...#....");
WillReturn.Add(".#..#..#..#..#....");
WillReturn.Add(".......####..#....");
WillReturn.Add(".............####.");
WillReturn.Add("..................");
WillReturn.Add("..................");
WillReturn.Add(".####.............");
WillReturn.Add("....#..#..#.......");
WillReturn.Add(".####..#..#..####.");
WillReturn.Add(".#.....####..#....");
WillReturn.Add(".####.....#..####.");
WillReturn.Add("..........#..#..#.");
WillReturn.Add(".............####.");
WillReturn.Add("..................");
//9
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static int mStaX;
static int mStaY;
static int mGoalX;
static int mGoalY;
static char[,] mBanArr;
static int UB_X;
static int UB_Y;
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => int.Parse(pX)).ToArray();
SplitAct(InputList[1]);
mStaX = wkArr[1] - 1;
mStaY = wkArr[0] - 1;
SplitAct(InputList[2]);
mGoalX = wkArr[1] - 1;
mGoalY = wkArr[0] - 1;
mBanArr = CreateBanArr(InputList.Skip(3));
UB_X = mBanArr.GetUpperBound(0);
UB_Y = mBanArr.GetUpperBound(1);
ExecBFS();
}
struct JyoutaiDef
{
internal int Curr_X;
internal int Curr_Y;
internal int Vect_X;
internal int Vect_Y;
internal int Level;
}
static void ExecBFS()
{
var Que = new Queue<JyoutaiDef>();
JyoutaiDef WillEnqueue;
WillEnqueue.Curr_X = mStaX;
WillEnqueue.Curr_Y = mStaY;
WillEnqueue.Vect_X = 0;
WillEnqueue.Vect_Y = 0;
WillEnqueue.Level = 0;
Que.Enqueue(WillEnqueue);
// 最小手数[ハッシュ値]
var MemoDict = new Dictionary<int, int>();
while (Que.Count > 0) {
JyoutaiDef Dequeued = Que.Dequeue();
// クリア判定
if (Dequeued.Curr_X == mGoalX && Dequeued.Curr_Y == mGoalY) {
Console.WriteLine(Dequeued.Level);
return;
}
Action<int, int> EnqueueAct = (pVect_X, pVect_Y) =>
{
// 前の移動のベクトルと、同じベクトルの場合
if (Dequeued.Vect_X == pVect_X && Dequeued.Vect_Y == pVect_Y) {
return;
}
// 前の移動のベクトルの、逆ベクトルの場合
if (-Dequeued.Vect_X == pVect_X && -Dequeued.Vect_Y == pVect_Y) {
return;
}
int CurrX = Dequeued.Curr_X;
int CurrY = Dequeued.Curr_Y;
while (true) {
CurrX += pVect_X;
CurrY += pVect_Y;
if (CurrX < 0 || UB_X < CurrX) return;
if (CurrY < 0 || UB_Y < CurrY) return;
if (mBanArr[CurrX, CurrY] == '#') return;
WillEnqueue.Curr_X = CurrX;
WillEnqueue.Curr_Y = CurrY;
WillEnqueue.Vect_X = pVect_X;
WillEnqueue.Vect_Y = pVect_Y;
WillEnqueue.Level = Dequeued.Level + 1;
int Hash = GetHash(WillEnqueue);
if (MemoDict.ContainsKey(Hash)) {
if (MemoDict[Hash] < WillEnqueue.Level) {
return;
}
}
MemoDict[Hash] = WillEnqueue.Level;
Que.Enqueue(WillEnqueue);
}
};
EnqueueAct(-1, -1);
EnqueueAct(-1, 1);
EnqueueAct(1, -1);
EnqueueAct(1, 1);
}
Console.WriteLine(-1);
}
static int GetHash(JyoutaiDef pJyoutai)
{
return pJyoutai.Curr_X * 10000 + pJyoutai.Curr_Y;
}
////////////////////////////////////////////////////////////////
// IEnumerable<string>をcharの2次元配列に設定する
////////////////////////////////////////////////////////////////
static char[,] CreateBanArr(IEnumerable<string> pStrEnum)
{
var StrList = pStrEnum.ToList();
if (StrList.Count == 0) {
return new char[0, 0];
}
int UB_X = StrList[0].Length - 1;
int UB_Y = StrList.Count - 1;
char[,] WillReturn = new char[UB_X + 1, UB_Y + 1];
for (int Y = 0; Y <= UB_Y; Y++) {
for (int X = 0; X <= UB_X; X++) {
WillReturn[X, Y] = StrList[Y][X];
}
}
return WillReturn;
}
}