AdventOfCode/Advent Of Code Library/2022/Day 09/RopeWalker.cs

70 lines
2.4 KiB
C#

namespace AdventOfCodeLibrary._2022.Day_09
{
internal class VirtualPoint
{
internal int X { get; set; } = 0;
internal int Y { get; set; } = 0;
internal void Translate(int x, int y)
{
X += x;
Y += y;
}
}
internal class RopeWalker
{
private readonly VirtualPoint HeadLocation = new();
private VirtualPoint LastHeadLocation = new();
private VirtualPoint TailLocation = new();
private List<string> TailVistedLocations = new();
internal int ProcessMovement(string[] movements)
{
// add the start position
TailVistedLocations.Add($"0,0");
for (int movementIndex = 0; movementIndex < movements.Length; movementIndex++)
{
char direction = movements[movementIndex][0];
int amountToMove = Convert.ToInt32(movements[movementIndex].Substring(2));
for (int movement = 0; movement < amountToMove; movement++)
{
// set the last pos before moving
LastHeadLocation.X = HeadLocation.X;
LastHeadLocation.Y = HeadLocation.Y;
// do the actual move
switch (direction)
{
case 'U': HeadLocation.Translate(0, 1); break;
case 'D': HeadLocation.Translate(0, -1); break;
case 'R': HeadLocation.Translate(1, 0); break;
case 'L': HeadLocation.Translate(-1, 0); break;
}
// check if the tail is touching
if (!IsTailTouchingHead(HeadLocation, TailLocation))
{
TailLocation.Translate(Math.Sign(HeadLocation.X - TailLocation.X), Math.Sign(HeadLocation.Y - TailLocation.Y));
// add the new position to the list of visited positions
TailVistedLocations.Add($"{TailLocation.X},{TailLocation.Y}");
}
}
}
return TailVistedLocations.Distinct().Count();
}
private bool IsTailTouchingHead(VirtualPoint point1, VirtualPoint point2)
{
return !(Math.Abs(point1.X - point2.X) > 1) && !(Math.Abs(point1.Y - point2.Y) > 1);
}
}
}