95 lines
2.9 KiB
C#
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(),
|
|
};
|
|
}
|
|
}
|
|
}
|