feat(*): Add 2021-10 part 2 files

This commit is contained in:
Josh Creek
2021-12-10 11:55:39 +00:00
parent f5937d3fd7
commit eb2ef8717f
2 changed files with 138 additions and 3 deletions
+101 -3
View File
@@ -1,4 +1,7 @@
namespace Day10
using System.Numerics;
using System.Text;
namespace Day10
{
class Program
{
@@ -10,8 +13,8 @@
string[] lines = File.ReadAllLines("input.txt");
Part1(lines);
//Part2(lines);
//Part1(lines);
Part2(lines);
}
static void Part1(string[] lines)
@@ -30,6 +33,64 @@
Console.WriteLine($"Syntax error score: {syntaxErrorScore}");
}
static void Part2(string[] lines)
{
List<string> uncorruptedLines = new List<string>();
int syntaxErrorScore = 0;
foreach (string line in lines)
{
if (!IsLineCorrupted(line, ref syntaxErrorScore))
{
uncorruptedLines.Add(line);
}
}
// Now we just have the incomplete lines, work out how to complete them
List<BigInteger> autoCompleteLineScores = new List<BigInteger>();
foreach (string line in uncorruptedLines)
{
BigInteger totalLineScore = 0;
string characters = GetCharactersToCompleteLine(line);
// Now calculate the score for the line
foreach (char character in characters)
{
totalLineScore = totalLineScore * 5;
switch (character)
{
case ')':
totalLineScore += 1;
break;
case ']':
totalLineScore += 2;
break;
case '}':
totalLineScore += 3;
break;
case '>':
totalLineScore += 4;
break;
default:
break;
}
}
autoCompleteLineScores.Add(totalLineScore);
Console.WriteLine($"{characters} - {totalLineScore} total points.");
}
// the winner is found by sorting all of the scores and then taking the middle score. (There will always be an odd number of scores to consider.)
autoCompleteLineScores.Sort();
BigInteger middleScore = autoCompleteLineScores.Skip(autoCompleteLineScores.Count / 2).Take(1).First();
Console.WriteLine($"Middle score: {middleScore}");
}
static bool IsLineCorrupted(string line, ref int syntaxErrorScore)
{
Stack<char> stackOfExpectedClosingCharacters = new Stack<char>();
@@ -85,6 +146,43 @@
return false;
}
static string GetCharactersToCompleteLine(string line)
{
Stack<char> stackOfExpectedClosingCharacters = new Stack<char>();
for (int i = 0; i < line.Length; i++)
{
if (openingCharacters.Contains(line[i]))
{
// If it's an opening character then add the expected closing character to the stack
stackOfExpectedClosingCharacters.Push(GetExpectedClosingCharacter(line[i]));
}
else if (closingCharacters.Contains(line[i]))
{
// If it's a closing character, then it must be the one we're expecting as we've already got rid of the corrupt lines
// Make sure there's items in the stack so we don't get an InvalidOperationException, then pop it off the stack
if (stackOfExpectedClosingCharacters.Count > 0)
{
stackOfExpectedClosingCharacters.Pop();
}
}
}
// The stack should now contain all the closing characters needed, in order, so get them into a string
StringBuilder charactersToCompleteLine = new StringBuilder();
while (stackOfExpectedClosingCharacters.Count > 0)
{
char character = stackOfExpectedClosingCharacters.Pop();
charactersToCompleteLine.Append(character);
}
Console.WriteLine($"Complete by adding {charactersToCompleteLine.ToString()}");
return charactersToCompleteLine.ToString();
}
static char GetExpectedClosingCharacter(char openingCharacter)
{
int index = openingCharacters.FindIndex(x => x == openingCharacter);