Add day 21
This commit is contained in:
183
Days/Day21.cs
Normal file
183
Days/Day21.cs
Normal file
@@ -0,0 +1,183 @@
|
||||
using System.Collections.Frozen;
|
||||
using System.Numerics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
using System.Text;
|
||||
using Spectre.Console;
|
||||
|
||||
namespace AdventOfCode.Days;
|
||||
|
||||
public class Day21 : Day
|
||||
{
|
||||
public override int Number => 21;
|
||||
public override string Name => "Keypad Conundrum";
|
||||
|
||||
private const char Up = '^';
|
||||
private const char Right = '>';
|
||||
private const char Down = 'v';
|
||||
private const char Left = '<';
|
||||
private const char Enter = 'A';
|
||||
|
||||
private readonly Dictionary<char, Point> _numpadPositions = new()
|
||||
{
|
||||
{ '7', (0, 0) },
|
||||
{ '8', (1, 0) },
|
||||
{ '9', (2, 0) },
|
||||
{ '4', (0, 1) },
|
||||
{ '5', (1, 1) },
|
||||
{ '6', (2, 1) },
|
||||
{ '1', (0, 2) },
|
||||
{ '2', (1, 2) },
|
||||
{ '3', (2, 2) },
|
||||
{ '0', (1, 3) },
|
||||
{ Enter, (2, 3) }
|
||||
};
|
||||
|
||||
private readonly Dictionary<char, Point> _keypadPositions = new()
|
||||
{
|
||||
{ Up, (1, 0) },
|
||||
{ Enter, (2, 0) },
|
||||
{ Left, (0, 1) },
|
||||
{ Down, (1, 1) },
|
||||
{ Right, (2, 1) }
|
||||
};
|
||||
|
||||
public override void RunPart1(bool display = true)
|
||||
{
|
||||
var codes = ParseCodes();
|
||||
var complexitiesSum = 0;
|
||||
|
||||
foreach (var code in codes)
|
||||
{
|
||||
// Get first keypad sequence
|
||||
var firstKeypadSequence = new StringBuilder();
|
||||
var currentInput = Enter;
|
||||
|
||||
foreach (var digit in code)
|
||||
{
|
||||
firstKeypadSequence.Append(GetNumpadMoveSequence(currentInput, digit));
|
||||
|
||||
currentInput = digit;
|
||||
}
|
||||
|
||||
// Get second keypad sequence
|
||||
var secondKeypadSequence = new StringBuilder();
|
||||
currentInput = Enter;
|
||||
|
||||
foreach (var input in firstKeypadSequence.ToString())
|
||||
{
|
||||
secondKeypadSequence.Append(GetKeypadMoveSequence(currentInput, input));
|
||||
|
||||
currentInput = input;
|
||||
}
|
||||
|
||||
// Get third and last keypad sequence
|
||||
var thirdKeypadSequence = new StringBuilder();
|
||||
currentInput = Enter;
|
||||
|
||||
foreach (var input in secondKeypadSequence.ToString())
|
||||
{
|
||||
thirdKeypadSequence.Append(GetKeypadMoveSequence(currentInput, input));
|
||||
|
||||
currentInput = input;
|
||||
}
|
||||
|
||||
complexitiesSum += thirdKeypadSequence.Length * int.Parse(code.AsSpan()[..^1]);
|
||||
}
|
||||
|
||||
if (display)
|
||||
{
|
||||
AnsiConsole.MarkupLine($"[green]Sum of complexities: [yellow]{complexitiesSum}[/][/]");
|
||||
}
|
||||
}
|
||||
|
||||
public override void RunPart2(bool display = true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private string GetNumpadMoveSequence(char origin, char destination)
|
||||
{
|
||||
var originPosition = _numpadPositions[origin];
|
||||
var destinationPosition = _numpadPositions[destination];
|
||||
|
||||
var move = destinationPosition - originPosition;
|
||||
|
||||
var moveRight = move.X > 0;
|
||||
var moveDown = move.Y > 0;
|
||||
|
||||
var sequence = string.Concat(
|
||||
new string(moveRight ? Right : Left, Math.Abs(move.X)),
|
||||
new string(moveDown ? Down : Up, Math.Abs(move.Y)),
|
||||
Enter.ToString() // Always end on Enter to press key
|
||||
);
|
||||
|
||||
return sequence;
|
||||
}
|
||||
|
||||
private string GetKeypadMoveSequence(char origin, char destination)
|
||||
{
|
||||
var originPosition = _keypadPositions[origin];
|
||||
var destinationPosition = _keypadPositions[destination];
|
||||
|
||||
var move = destinationPosition - originPosition;
|
||||
|
||||
var moveRight = move.X > 0;
|
||||
var moveDown = move.Y > 0;
|
||||
|
||||
var sequence = string.Concat(
|
||||
new string(moveDown ? Down : Up, Math.Abs(move.Y)),
|
||||
new string(moveRight ? Right : Left, Math.Abs(move.X)),
|
||||
Enter.ToString() // Always end on Enter to press key
|
||||
);
|
||||
|
||||
return sequence;
|
||||
}
|
||||
|
||||
private List<string> ParseCodes()
|
||||
{
|
||||
var codes = new List<string>();
|
||||
|
||||
foreach (var line in Input.AsSpan().EnumerateLines())
|
||||
{
|
||||
codes.Add(line.ToString());
|
||||
}
|
||||
|
||||
return codes;
|
||||
}
|
||||
|
||||
private readonly record struct Point(int X, int Y)
|
||||
: IAdditionOperators<Point, Point, Point>,
|
||||
ISubtractionOperators<Point, Point, Point>,
|
||||
IMultiplyOperators<Point, int, Point>
|
||||
{
|
||||
public static Point operator +(Point left, Point right)
|
||||
{
|
||||
return new Point(left.X + right.X, left.Y + right.Y);
|
||||
}
|
||||
|
||||
public static Point operator -(Point left, Point right)
|
||||
{
|
||||
return new Point(left.X - right.X, left.Y - right.Y);
|
||||
}
|
||||
|
||||
public static Point operator *(Point left, int right)
|
||||
{
|
||||
return new Point(left.X * right, left.Y * right);
|
||||
}
|
||||
|
||||
public static Point operator *(int left, Point right)
|
||||
{
|
||||
return new Point(right.X * left, right.Y * left);
|
||||
}
|
||||
|
||||
public static implicit operator Point((int X, int Y) point)
|
||||
=> new(point.X, point.Y);
|
||||
|
||||
public int DistanceTo(Point other)
|
||||
{
|
||||
var distance = other - this;
|
||||
|
||||
return Math.Abs(distance.X) + Math.Abs(distance.Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
5
Inputs/Day21.txt
Normal file
5
Inputs/Day21.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
029A
|
||||
980A
|
||||
179A
|
||||
456A
|
||||
379A
|
||||
Reference in New Issue
Block a user