171 lines
4.3 KiB
C#
171 lines
4.3 KiB
C#
using System.Numerics;
|
|
using System.Text.RegularExpressions;
|
|
|
|
var exParsed = new Day03Parsed("example-input.txt");
|
|
var ex2Parsed = new Day03Parsed("example-input2.txt");
|
|
|
|
Console.WriteLine("Example Part01: {0}", exParsed.GetPart01());
|
|
Console.WriteLine("Example Part02: {0}", ex2Parsed.GetPart02());
|
|
|
|
var pzParsed = new Day03Parsed("puzzle-input.txt");
|
|
|
|
Console.WriteLine("Puzzle Part01: {0}", pzParsed.GetPart01());
|
|
Console.WriteLine("Puzzle Part02: {0}", pzParsed.GetPart02());
|
|
|
|
|
|
public class Mul
|
|
{
|
|
private static readonly int INVALID_VALUE = 9999;
|
|
|
|
private int leftOperand = INVALID_VALUE;
|
|
private int rightOperand = INVALID_VALUE;
|
|
|
|
public int LeftOperand { get { return leftOperand; } }
|
|
public int RightOperand { get { return rightOperand; } }
|
|
|
|
public Mul(string line)
|
|
{
|
|
try
|
|
{
|
|
var split = line.Split(',');
|
|
|
|
// left side
|
|
var leftOperand = split[0].Substring("mul(".Length);
|
|
System.Diagnostics.Debug.Assert(leftOperand.Length <= 3);
|
|
|
|
this.leftOperand = Int32.Parse(leftOperand);
|
|
|
|
// right side
|
|
var rightOperand = split[1].Split(')')[0];
|
|
System.Diagnostics.Debug.Assert(rightOperand.Length <= 3);
|
|
|
|
this.rightOperand = Int32.Parse(rightOperand);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
public bool IsValid()
|
|
{
|
|
return leftOperand != INVALID_VALUE && rightOperand != INVALID_VALUE;
|
|
}
|
|
|
|
public int GetResult()
|
|
{
|
|
if (!IsValid()) throw new Exception("OBJECT INVALID YO");
|
|
|
|
return leftOperand * rightOperand;
|
|
}
|
|
}
|
|
|
|
class Day03Parsed : AdventCommon.ParsedInput
|
|
{
|
|
public Day03Parsed(string fileName) : base(fileName)
|
|
{
|
|
|
|
}
|
|
|
|
private int part01 = 0;
|
|
private int part02 = 0;
|
|
|
|
private void UpdatePart01(string line)
|
|
{
|
|
string pattern = @"mul\([0-9]{1,3},[0-9]{1,3}\)";
|
|
|
|
var m = Regex.Match(line, pattern);
|
|
|
|
while (m.Success)
|
|
{
|
|
var mul = new Mul(m.Value);
|
|
part01 += mul.GetResult();
|
|
|
|
//Console.WriteLine("'{0}' found at position {1}", m.Value, m.Index);
|
|
m = m.NextMatch();
|
|
}
|
|
}
|
|
|
|
private bool UpdatePart02(string line, bool lastMul)
|
|
{
|
|
bool mulEnabled = lastMul;
|
|
|
|
SortedDictionary<int, string> ops = new SortedDictionary<int, string>();
|
|
|
|
string[] patterns = [
|
|
@"mul\([0-9]{1,3},[0-9]{1,3}\)",
|
|
@"do\(\)",
|
|
@"don't\(\)"
|
|
];
|
|
|
|
foreach (var pattern in patterns)
|
|
{
|
|
for (var r = Regex.Match(line, pattern); r.Success; r = r.NextMatch())
|
|
{
|
|
ops.Add(r.Index, r.Value);
|
|
}
|
|
}
|
|
|
|
foreach (var op in ops)
|
|
{
|
|
//Console.WriteLine("{ " + op.Value + " }");
|
|
|
|
string canary = "mul(549,60)";
|
|
if (op.Value.Contains(canary))
|
|
{
|
|
//Console.WriteLine("poop");
|
|
}
|
|
|
|
if (mulEnabled)
|
|
{
|
|
var m = new Mul(op.Value);
|
|
|
|
if (m.IsValid())
|
|
{
|
|
part02 += m.GetResult();
|
|
|
|
// Console.WriteLine("Added: {0}", m.GetResult());
|
|
//Console.WriteLine("New: {0}", part02);
|
|
}
|
|
|
|
// m not valid, is it a don't?
|
|
if (op.Value.Contains("don't"))
|
|
{
|
|
//Console.WriteLine("Setting do() to false");
|
|
mulEnabled = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (op.Value.Contains("do()"))
|
|
{
|
|
//Console.WriteLine("Setting do() to true");
|
|
mulEnabled = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return mulEnabled;
|
|
}
|
|
|
|
private bool lastMulEnabled = true;
|
|
|
|
public override bool ParseLine(string line, object? context = null)
|
|
{
|
|
UpdatePart01(line);
|
|
|
|
lastMulEnabled = UpdatePart02(line, lastMulEnabled);
|
|
|
|
return true;
|
|
}
|
|
|
|
public override int GetPart01()
|
|
{
|
|
return part01;
|
|
}
|
|
|
|
public override int GetPart02()
|
|
{
|
|
return part02;
|
|
}
|
|
} |