Files
2021/src/12.cs
Parnic 9e7942a35e Enable running all days at once
I'm kinda bored and wanted to.
2021-12-12 15:28:41 -06:00

112 lines
3.5 KiB
C#

namespace aoc2021;
internal class Day12 : Day
{
internal override void Go()
{
Logger.Log("Day 12");
Logger.Log("-----");
var lines = File.ReadAllLines("inputs/12.txt");
var paths = new Dictionary<string, List<string>>();
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>();
}
if (!paths.ContainsKey(points[1]))
{
paths[points[1]] = new List<string>();
}
if (points[0] != "END" && points[1] != "START")
{
paths[points[0]].Add(points[1]);
}
if (points[1] != "END" && points[0] != "START")
{
paths[points[1]].Add(points[0]);
}
}
Part1(paths);
Part2(paths);
Logger.Log("");
}
private static void Part1(Dictionary<string, List<string>> paths)
{
using var t = new Timer();
var validPaths = new List<List<string>>();
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 (IsSmallCave(next) && currRoute.Contains(next))
{
if (!canVisitSmallCaveTwice || hasDoubledCave)
{
//Logger.Log($" is already-visited small cave, skipping");
continue;
}
hasDoubledCave = true;
justDoubled = true;
}
//Logger.Log($" adding to route");
currRoute.Add(next);
if (next == "END")
{
//Logger.Log($" is end, so adding {string.Join(',', currRoute)} to valid paths");
routes.Add(new List<string>(currRoute));
}
else
{
FindPaths(paths, routes, currRoute, canVisitSmallCaveTwice, hasDoubledCave);
}
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);
Logger.Log($"part2: {validPaths.Count}");
//validPaths.ForEach(path => Logger.Log($" {string.Join(',', path)}"));
}
}