|
|
@@ -113,7 +113,7 @@ namespace D20._1
|
|
|
file.Close();
|
|
|
|
|
|
//regex = @"^ENNWSWW(NEWS|)SSSEEN(WNSE|)EE(SWEN|)NNN$";
|
|
|
- regex = @"^WSSEESWWWNW(S|NENNEEEENN(ESSSSW(NWSW|SSEN)|WSWWN(E|WWS(E|SS))))$";
|
|
|
+ //regex = @"^WSSEESWWWNW(S|NENNEEEENN(ESSSSW(NWSW|SSEN)|WSWWN(E|WWS(E|SS))))$";
|
|
|
//regex = @"^N(EEENWWW|N)$";
|
|
|
|
|
|
regex = regex.TrimStart('^').TrimEnd('$');
|
|
|
@@ -140,20 +140,22 @@ namespace D20._1
|
|
|
|
|
|
Console.WriteLine(sw.ElapsedMilliseconds);
|
|
|
|
|
|
- int max = 0;
|
|
|
+ Dictionary<(int x, int y), int> positions = new Dictionary<(int x, int y), int>();
|
|
|
foreach (var path in root.Possibilities)
|
|
|
{
|
|
|
- var r = GetResult(path);
|
|
|
- if (r > max) max = r;
|
|
|
+ TestResult(path, positions);
|
|
|
}
|
|
|
|
|
|
+ int max = positions.Max(p => p.Value);
|
|
|
Console.WriteLine(max);
|
|
|
}
|
|
|
|
|
|
- private static int GetResult(string str)
|
|
|
+ private static void TestResult(string str, Dictionary<(int x, int y), int> positions)
|
|
|
{
|
|
|
(int x, int y) pos = (0, 0);
|
|
|
- HashSet<((int x, int y) from, (int x, int y) to)> doors = new HashSet<((int x, int y) from, (int x, int y) to)>();
|
|
|
+ int dist = 0;
|
|
|
+
|
|
|
+ positions.TryAdd(pos, 0);
|
|
|
foreach (var c in str)
|
|
|
{
|
|
|
var bpos = pos;
|
|
|
@@ -165,71 +167,11 @@ namespace D20._1
|
|
|
case 'E': pos.x += 1; break;
|
|
|
}
|
|
|
|
|
|
- doors.Add((bpos, pos));
|
|
|
- doors.Add((pos, bpos));
|
|
|
+ dist++;
|
|
|
+ if (positions.TryAdd(pos, dist) == false)
|
|
|
+ dist = Math.Min(dist + 1, positions[pos]);
|
|
|
+ positions[pos] = dist;
|
|
|
}
|
|
|
-
|
|
|
- return GetBreadthFirstSearch(doors, pos);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // https://en.wikipedia.org/wiki/Breadth-first_search
|
|
|
- private static int GetBreadthFirstSearch(HashSet<((int x, int y) from, (int x, int y) to)> doors, (int x, int y) togo)
|
|
|
- {
|
|
|
- var nodesToVisit = new Queue<(int x, int y)>();
|
|
|
- var visitedNodes = new HashSet<(int x, int y)>();
|
|
|
- var meta = new Dictionary<(int x, int y), (int x, int y)>()
|
|
|
- {
|
|
|
- { (0, 0), (0, 0) }
|
|
|
- };
|
|
|
-
|
|
|
- nodesToVisit.Enqueue((0, 0));
|
|
|
-
|
|
|
- while (nodesToVisit.Count > 0)
|
|
|
- {
|
|
|
- var node = nodesToVisit.Dequeue();
|
|
|
-
|
|
|
- // Found it!
|
|
|
- if (node == togo)
|
|
|
- {
|
|
|
- var count = GetActionList(togo, meta, node);
|
|
|
- return count;
|
|
|
- }
|
|
|
-
|
|
|
- foreach ((int mx, int my) mv in new []{ (0, -1), (1, 0), (0, 1), (-1, 0) })
|
|
|
- {
|
|
|
- (int x, int y) successor = (node.x + mv.mx, node.y + mv.my);
|
|
|
-
|
|
|
- // Continue if no door exist
|
|
|
- if (doors.Contains((node, successor)) == false) continue;
|
|
|
-
|
|
|
- if (visitedNodes.Contains(successor)) continue;
|
|
|
-
|
|
|
- if (nodesToVisit.Contains(successor) == false)
|
|
|
- {
|
|
|
- meta.TryAdd(successor, mv);
|
|
|
- nodesToVisit.Enqueue(successor);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- visitedNodes.Add(node);
|
|
|
- }
|
|
|
-
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- private static int GetActionList((int x, int y) root, Dictionary<(int x, int y), (int x, int y)> meta, (int x, int y) node)
|
|
|
- {
|
|
|
- var actionList = new List<(int x, int y)>();
|
|
|
-
|
|
|
- while (meta[node] != (0, 0))
|
|
|
- {
|
|
|
- var action = meta[node];
|
|
|
- node = (node.x - action.x, node.y - action.y);
|
|
|
- actionList.Add(action);
|
|
|
- }
|
|
|
-
|
|
|
- return actionList.Count;
|
|
|
}
|
|
|
}
|
|
|
}
|