using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace _2021___Day_12
{
public static class Program
{
static string[] input = File.ReadAllLines("../../../../Input.in");
static List<string> paths = new List<string>();
static List<string> pathsP2 = new List<string>();
static Dictionary<string, Node> nodes = new Dictionary<string, Node>();
public static void Main()
{
foreach (string s in input)
{
string[] temp = s.Split('-');
if (!nodes.ContainsKey(temp[0]))
nodes.Add(temp[0], new Node(temp[0]));
if (!nodes.ContainsKey(temp[1]))
nodes.Add(temp[1], new Node(temp[1]));
}
foreach (string s in input)
{
string[] temp = s.Split('-');
nodes[temp[0]].AddConnection(temp[1], nodes[temp[1]]);
nodes[temp[1]].AddConnection(temp[0], nodes[temp[0]]);
}
BuildPaths("start", "", "");
int counter = 0;
foreach (string s in paths)
{
bool onlyLarge = true;
string[] temp = s.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
foreach (string l in temp)
{
if (l != "start" && l != "end")
{
if (!(l[0] >= 'A' && l[0] <= 'Z'))
{
onlyLarge = false;
}
}
}
if (!onlyLarge)
{
counter++;
}
}
Console.WriteLine("There are " + counter.ToString() + "paths with the given input");
BuildPathsAgain("start", "", "", false);
Console.WriteLine("There are " + pathsP2.Count() + " paths with the new rules");
}
public static void BuildPaths(string nextNode, string path, string smallVisited)
{
string pathSoFar = path;
pathSoFar += nextNode + ",";
if (!nodes[nextNode].isLarge)
smallVisited += nextNode + ",";
if (nextNode == "end")
{
paths.Add(pathSoFar);
return;
}
string[] temp = smallVisited.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
foreach (KeyValuePair<string, Node> kvp in nodes[nextNode].Connections)
{
if (!temp.Contains(kvp.Key))
BuildPaths(kvp.Key, pathSoFar, smallVisited);
}
}
public static void BuildPathsAgain(string nextNode, string path, string smallVisited, bool smallTwice)
{
string pathSoFar = path;
bool smallTwiceNext = smallTwice;
pathSoFar += nextNode + ",";
if (!nodes[nextNode].isLarge)
smallVisited += nextNode + ",";
if (nextNode == "end")
{
pathsP2.Add(pathSoFar);
return;
}
string[] temp = smallVisited.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
List<string> smallTwiceCheck = new List<string>();
foreach (string s in temp)
{
if (smallTwiceCheck.Contains(s))
{
smallTwiceNext = true;
}
else
{
smallTwiceCheck.Add(s);
}
}
foreach (KeyValuePair<string, Node> kvp in nodes[nextNode].Connections)
{
if (kvp.Key != "start")
{
if (smallTwiceNext)
{
if (!temp.Contains(kvp.Key))
BuildPathsAgain(kvp.Key, pathSoFar, smallVisited, smallTwiceNext);
}
else
{
BuildPathsAgain(kvp.Key, pathSoFar, smallVisited, smallTwiceNext);
}
}
}
}
}
public class Node
{
public string Name { get; set; }
public bool isLarge { get; set; }
public Dictionary<string, Node> Connections { get; set; }
public Node(string name)
{
Name = name;
if (name[0] >= 'A' && name[0] <= 'Z')
isLarge = true;
else
isLarge = false;
Connections = new Dictionary<string, Node>();
}
public void AddConnection(string name, Node n)
{
Connections.Add(name, n);
}
}
}