More day 12 optimizations
Down to ~98ms from the original ~940ms. That's a very respectable gain, but I am still not quite happy with the runtime. At this point, though, I think I will need to re-think my approach rather than making small tweaks.
This commit is contained in:
40
src/12.cs
40
src/12.cs
@ -11,6 +11,15 @@ internal class Day12
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var points = line.Split('-');
|
||||
if (points[0] == "start" || points[0] == "end")
|
||||
{
|
||||
points[0] = points[0].ToUpper();
|
||||
}
|
||||
if (points[1] == "start" || points[1] == "end")
|
||||
{
|
||||
points[1] = points[1].ToUpper();
|
||||
}
|
||||
|
||||
if (!paths.ContainsKey(points[0]))
|
||||
{
|
||||
paths[points[0]] = new List<string>();
|
||||
@ -20,11 +29,11 @@ internal class Day12
|
||||
paths[points[1]] = new List<string>();
|
||||
}
|
||||
|
||||
if (points[0] != "end" && points[1] != "start")
|
||||
if (points[0] != "END" && points[1] != "START")
|
||||
{
|
||||
paths[points[0]].Add(points[1]);
|
||||
}
|
||||
if (points[1] != "end" && points[0] != "start")
|
||||
if (points[1] != "END" && points[0] != "START")
|
||||
{
|
||||
paths[points[1]].Add(points[0]);
|
||||
}
|
||||
@ -39,35 +48,35 @@ internal class Day12
|
||||
using var t = new Timer();
|
||||
|
||||
var validPaths = new List<List<string>>();
|
||||
FindPaths(paths, validPaths, new List<string>(){ "start" }, false);
|
||||
FindPaths(paths, validPaths, new List<string>(){ "START" }, false);
|
||||
|
||||
Logger.Log($"part1: {validPaths.Count}");
|
||||
//validPaths.ForEach(path => Logger.Log($" {string.Join(',', path)}"));
|
||||
}
|
||||
|
||||
private static void FindPaths(Dictionary<string, List<string>> paths, List<List<string>> routes, List<string> currRoute, bool canVisitSmallCaveTwice, bool hasDoubledCave = false)
|
||||
{
|
||||
//Logger.Log($"Current path: {string.Join(',', currRoute)}");
|
||||
var curr = currRoute.Last();
|
||||
bool justDoubled = false;
|
||||
foreach (var next in paths[curr])
|
||||
{
|
||||
//Logger.Log($" Evaluating next: {next}");
|
||||
if (next != "end" && next.ToLower() == next && currRoute.Contains(next))
|
||||
if (IsSmallCave(next) && currRoute.Contains(next))
|
||||
{
|
||||
if (!canVisitSmallCaveTwice || hasDoubledCave)
|
||||
{
|
||||
//Logger.Log($" is already-visited small cave, skipping");
|
||||
continue;
|
||||
}
|
||||
else if (currRoute.Any(x => x[0] >= 'a' && x[0] <= 'z' && currRoute.Count(y => x == y) == 2))
|
||||
{
|
||||
//Logger.Log($" is already-visited small cave and we have already been to another one twice, skipping");
|
||||
hasDoubledCave = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
hasDoubledCave = true;
|
||||
justDoubled = true;
|
||||
}
|
||||
|
||||
//Logger.Log($" adding to route");
|
||||
currRoute.Add(next);
|
||||
if (next == "end")
|
||||
if (next == "END")
|
||||
{
|
||||
//Logger.Log($" is end, so adding {string.Join(',', currRoute)} to valid paths");
|
||||
routes.Add(new List<string>(currRoute));
|
||||
@ -78,18 +87,25 @@ internal class Day12
|
||||
}
|
||||
|
||||
currRoute.RemoveAt(currRoute.Count - 1);
|
||||
if (justDoubled)
|
||||
{
|
||||
hasDoubledCave = false;
|
||||
}
|
||||
}
|
||||
|
||||
//Logger.Log(" done with route");
|
||||
}
|
||||
|
||||
private static bool IsSmallCave(string cave) => cave[0] >= 'a' && cave[0] <= 'z';
|
||||
|
||||
private static void Part2(Dictionary<string, List<string>> paths)
|
||||
{
|
||||
using var t = new Timer();
|
||||
|
||||
var validPaths = new List<List<string>>();
|
||||
FindPaths(paths, validPaths, new List<string>() { "start" }, true);
|
||||
FindPaths(paths, validPaths, new List<string>() { "START" }, true);
|
||||
|
||||
Logger.Log($"part2: {validPaths.Count}");
|
||||
//validPaths.ForEach(path => Logger.Log($" {string.Join(',', path)}"));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user