AdventOfCode/Advent Of Code Library/2022/Day 09/RopeWalker.cs
2022-12-09 14:28:25 +01:00

95 lines
2.9 KiB
C#

namespace AdventOfCodeLibrary._2022.Day_09
{
internal class VirtualPoint
{
internal int X { get; private set; } = 0;
internal int Y { get; private set; } = 0;
internal void MoveUp()
{
Y++;
}
internal void MoveDown()
{
Y--;
}
internal void MoveRight()
{
X++;
}
internal void MoveLeft()
{
X--;
}
}
internal class RopeWalker
{
private 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 = HeadLocation;
// do the actual move
switch (direction)
{
case 'U': HeadLocation.MoveUp(); break;
case 'D': HeadLocation.MoveDown(); break;
case 'R': HeadLocation.MoveRight(); break;
case 'L': HeadLocation.MoveLeft(); break;
}
// check if the tail is touching
if (!IsTailTouchingHead(direction))
{
// if not, move tail to last head position
TailLocation = LastHeadLocation;
// add the new position to the list of visited positions
TailVistedLocations.Add($"{TailLocation.X},{TailLocation.Y}");
}
}
}
return TailVistedLocations.Distinct().Count();
}
private bool IsTailTouchingHead(char direction)
{
return direction switch
{
// up; Y + 1
'U' => TailLocation.Y + 1 >= HeadLocation.Y,
// down; Y - 1
'D' => TailLocation.Y - 1 <= HeadLocation.Y,
// right; X + 1
'R' => TailLocation.X + 1 >= HeadLocation.X,
// left; X - 1
'L' => TailLocation.X - 1 <= HeadLocation.X,
_ => throw new AccessViolationException(),
};
}
}
}