Files
AdventOfCode/Days/Day9.cs

2149 lines
21 KiB
C#

using Spectre.Console;
namespace AdventOfCode.Days;
public class Day9 : Day
{
public override int Number => 9;
public override string Name => "Rope Bridge";
public override void RunPart1(bool display = true)
{
// Start
(int x, int y) start = (0, 0);
var headPosition = start;
var tailPosition = start;
var tailVisitedPositions = new HashSet<(int x, int y)> { tailPosition };
// Do head movements
foreach (var line in Input.ReadAllLines())
{
var split = line.Split(' ');
var direction = split[0];
var count = int.Parse(split[1]);
// Do the movement in direction 'count' times
for (int i = 0; i < count; i++)
{
var oldHeadPosition = headPosition;
// Move the head
headPosition = direction switch
{
"U" => (headPosition.x, headPosition.y + 1),
"D" => (headPosition.x, headPosition.y - 1),
"R" => (headPosition.x + 1, headPosition.y),
"L" => (headPosition.x - 1, headPosition.y),
_ => throw new ArgumentOutOfRangeException(nameof(direction))
};
// Check if the tail is too far away
if (Math.Abs(tailPosition.x - headPosition.x) >= 2
|| Math.Abs(tailPosition.y - headPosition.y) >= 2)
{
// Move the tail
tailPosition = oldHeadPosition;
tailVisitedPositions.Add(tailPosition);
}
}
}
if (display)
{
AnsiConsole.MarkupLine($"[green]The tail visited [yellow]{tailVisitedPositions.Count}[/] unique positions[/]");
}
}
public override void RunPart2(bool display = true)
{
const int tailSegments = 9;
// Start
(int x, int y) start = (0, 0);
var headPosition = start;
var tailPositions = Enumerable.Repeat(start, tailSegments).ToArray();
var tailVisitedPositions = new HashSet<(int x, int y)> { start };
// Do head movements
foreach (var line in Input.ReadAllLines())
{
var split = line.Split(' ');
var direction = split[0];
var count = int.Parse(split[1]);
// Do the movement in direction 'count' times
for (int i = 0; i < count; i++)
{
// Move the head
headPosition = direction switch
{
"U" => (headPosition.x, headPosition.y + 1),
"D" => (headPosition.x, headPosition.y - 1),
"R" => (headPosition.x + 1, headPosition.y),
"L" => (headPosition.x - 1, headPosition.y),
_ => throw new ArgumentOutOfRangeException(nameof(direction))
};
// Move each segment of the tail if needed
for (int tail = 0; tail < tailSegments; tail++)
{
// Check if the tail is too far away from previous segment
var tailPosition = tailPositions[tail];
var previousTailPosition = tail > 0 ? tailPositions[tail - 1] : headPosition;
var dx = previousTailPosition.x - tailPosition.x;
var dy = previousTailPosition.y - tailPosition.y;
// Don't move the tail if it's still next to previous tail
if ((Math.Abs(dx), Math.Abs(dy)) is not ((>= 2, _) or (_, >= 2)))
{
continue;
}
// Move the tail segment
tailPositions[tail] = (dx, dy) switch
{
// Top right
(>= 2, >= 1) or (>= 1, >= 2) => (tailPosition.x + 1, tailPosition.y + 1),
// Top left
(<= -2, >= 1) or (<= -1, >= 2) => (tailPosition.x - 1, tailPosition.y + 1),
// Bottom right
(>= 2, <= -1) or (>= 1, <= -2) => (tailPosition.x + 1, tailPosition.y - 1),
// Bottom left
(<= -2, <= -1) or (<= -1, <= -2) => (tailPosition.x - 1, tailPosition.y - 1),
// Top
(_, >= 2) => (tailPosition.x, tailPosition.y + 1),
// Bottom
(_, <= -2) => (tailPosition.x, tailPosition.y -1),
// Right
(>= 2, _) => (tailPosition.x + 1, tailPosition.y),
// Left
(<= -2, _) => (tailPosition.x - 1, tailPosition.y),
// Impossible to get there
_ => throw new Exception("How did you get there")
};
// Visit positions for the tail end (9)
if (tail == tailSegments - 1)
{
tailVisitedPositions.Add(tailPositions[tail]);
}
}
}
}
if (display)
{
AnsiConsole.MarkupLine($"[green]The tail visited [yellow]{tailVisitedPositions.Count}[/] unique positions[/]");
}
}
#region Input
public const string Input =
"""
L 1
D 2
U 1
L 1
R 2
L 2
U 1
D 2
R 2
L 2
U 1
D 2
R 1
D 2
L 2
D 1
L 2
R 1
U 2
R 2
U 2
L 2
U 1
L 2
R 1
D 1
R 1
L 1
R 1
L 1
R 1
U 1
R 1
L 1
D 2
L 2
D 2
L 1
R 1
D 1
R 1
D 2
L 1
D 2
L 1
R 2
D 2
R 2
U 1
R 1
U 2
R 1
U 2
R 1
D 2
L 1
D 2
U 1
R 2
D 2
L 1
U 2
R 2
L 2
D 2
L 2
D 2
R 1
U 2
L 2
U 1
R 1
D 1
L 1
D 1
U 1
D 2
L 1
R 1
D 1
R 1
L 2
R 1
L 1
U 2
D 2
U 1
L 1
U 2
R 1
D 2
U 1
D 1
L 1
D 2
U 2
D 1
U 2
R 2
L 2
D 1
R 2
D 1
L 2
D 2
L 2
R 1
L 1
R 2
L 2
R 2
U 1
R 1
U 3
D 2
U 3
L 1
R 1
U 3
D 1
L 1
R 3
D 2
L 3
R 3
D 2
R 2
U 3
R 3
U 3
R 2
U 3
D 2
L 3
U 3
R 1
U 1
R 3
U 2
L 1
R 1
U 1
L 3
R 3
U 3
D 2
U 1
L 1
D 3
R 3
U 2
L 1
R 3
L 3
D 3
U 3
R 2
L 1
U 1
L 3
R 3
U 1
R 3
L 2
R 2
D 3
U 1
D 3
U 3
R 3
D 2
L 2
U 2
D 3
L 3
U 3
R 3
D 2
R 3
U 1
D 1
U 2
R 1
D 3
R 1
L 2
U 3
D 1
L 1
D 3
U 2
L 3
R 3
L 1
D 2
L 3
U 3
L 1
D 2
L 1
D 1
L 2
U 2
D 2
U 2
L 2
D 3
L 3
D 3
R 3
U 1
R 3
U 1
R 3
D 3
U 2
D 1
R 2
L 2
R 2
D 2
R 2
D 1
R 3
D 1
U 2
L 4
D 1
L 2
R 1
U 1
D 3
U 4
D 2
L 3
R 2
D 3
R 4
U 1
D 1
U 1
L 3
U 1
D 3
R 3
D 3
R 1
U 4
R 1
U 1
R 2
L 4
U 3
D 2
R 2
D 1
U 2
L 3
D 4
U 4
D 4
U 4
L 3
U 3
D 3
R 3
L 4
R 3
D 2
L 2
R 1
D 1
L 4
R 3
D 2
U 1
L 2
R 1
U 2
L 4
R 4
L 3
U 4
D 2
U 4
D 4
L 1
U 4
L 3
U 2
D 2
R 2
D 3
R 4
D 1
U 4
D 1
U 1
D 3
L 3
D 2
R 4
D 4
L 2
U 2
L 3
R 4
L 2
R 2
D 3
L 2
D 4
U 3
D 4
L 3
R 2
U 3
D 4
R 2
U 3
R 1
D 1
R 1
D 2
R 3
D 4
L 1
U 3
L 3
U 4
R 1
U 3
L 4
D 5
R 2
D 2
U 2
D 1
R 4
D 1
L 4
D 4
L 1
R 1
D 4
U 4
L 1
D 4
L 4
U 5
R 4
D 4
R 5
U 3
L 5
U 1
R 4
L 1
R 3
L 2
D 5
R 1
D 4
R 2
U 5
L 3
R 5
U 4
R 1
D 4
U 3
R 3
L 3
R 3
L 3
U 2
D 4
U 2
L 3
D 2
R 3
U 3
D 2
U 1
R 5
L 4
R 4
L 4
D 3
R 3
U 2
R 1
D 3
U 3
D 2
L 1
D 2
U 1
L 3
U 5
L 1
D 1
U 5
D 3
U 4
D 4
L 5
R 3
D 4
R 2
L 1
D 1
L 3
U 3
R 1
L 2
D 4
L 5
U 1
L 4
R 4
U 2
D 1
R 5
D 3
U 2
D 3
U 4
D 4
U 1
L 2
D 4
L 3
U 4
L 1
R 1
L 2
R 3
L 2
U 1
D 2
U 5
R 2
D 4
U 1
D 4
U 4
D 5
L 6
D 3
U 2
D 1
L 3
U 4
R 4
D 4
R 3
L 4
U 6
D 1
U 4
R 2
L 1
D 2
U 4
D 5
U 3
D 6
L 1
U 3
L 1
U 1
D 6
L 3
U 6
L 3
D 6
L 1
D 6
U 2
D 5
U 2
L 5
D 3
U 2
D 1
U 6
L 1
D 4
L 6
R 3
D 3
L 3
D 2
R 3
D 5
R 3
D 2
L 1
R 4
L 6
D 4
R 4
U 1
R 6
D 3
U 1
R 1
D 1
L 3
D 1
R 3
U 5
L 5
D 2
L 3
D 2
L 5
U 3
L 1
U 5
L 3
D 4
U 5
D 1
L 6
D 1
R 6
U 4
R 1
D 1
L 2
U 5
R 2
U 6
L 5
U 5
L 6
U 6
D 3
L 1
R 3
L 3
U 4
R 5
L 6
D 5
L 4
R 6
L 6
R 5
D 2
R 4
L 2
U 1
L 3
U 6
L 4
D 6
U 6
D 4
L 2
R 7
U 4
R 1
L 5
D 2
R 3
U 4
L 5
U 7
L 2
R 1
U 4
L 2
R 5
L 6
D 5
L 4
U 5
L 7
U 1
L 5
U 1
L 5
D 3
U 3
R 7
U 7
R 7
L 6
D 4
U 7
R 2
D 3
R 3
U 4
D 4
U 5
D 6
L 5
R 6
U 4
R 6
D 1
R 4
U 1
D 1
R 1
L 4
U 5
L 3
D 5
L 5
D 3
U 2
R 5
D 7
U 7
D 1
U 5
R 6
U 4
R 6
L 7
U 5
R 1
L 1
U 1
R 1
D 7
L 2
U 5
R 4
U 2
D 6
U 6
L 7
U 3
D 2
L 3
R 3
U 2
L 1
R 2
L 5
D 6
R 2
U 6
L 1
D 7
R 4
D 3
L 2
U 5
R 4
L 2
R 5
D 1
U 1
R 6
D 5
U 6
R 2
U 2
L 2
U 6
L 5
U 1
L 1
D 7
R 6
U 5
D 3
L 5
R 3
D 3
U 2
D 7
U 7
L 1
D 5
L 5
U 4
L 5
D 1
U 6
D 5
L 7
D 8
U 8
R 6
U 5
D 8
U 1
R 2
U 6
D 6
L 4
D 2
R 3
U 7
R 4
U 4
R 5
U 6
R 1
U 4
R 1
U 4
D 5
U 3
L 7
U 8
R 1
D 1
U 8
L 8
U 3
L 1
D 4
R 2
D 4
U 2
L 4
D 8
R 7
D 5
U 4
L 5
U 5
D 8
R 8
U 3
R 8
L 4
U 5
R 6
U 7
D 3
L 1
U 5
D 2
R 5
U 4
D 8
L 4
R 1
D 6
R 1
L 6
D 6
L 7
D 4
L 4
D 8
R 8
D 7
L 6
R 1
D 4
L 5
D 2
U 3
D 2
U 6
R 1
U 7
D 7
R 2
U 7
D 5
L 6
U 1
L 8
U 1
L 1
R 9
D 1
U 6
D 5
L 1
R 9
D 2
L 2
D 6
U 6
D 7
L 3
R 5
L 6
U 5
R 1
U 1
R 3
L 9
U 6
L 6
U 2
D 6
R 9
U 4
D 3
L 8
U 5
D 7
L 1
U 7
R 1
L 6
D 8
L 5
R 7
L 2
R 6
L 5
D 3
L 8
D 7
U 8
R 6
L 6
D 7
U 8
D 1
U 2
D 5
U 7
D 8
L 1
D 1
L 1
U 1
R 3
L 5
R 9
D 2
L 8
R 6
D 6
U 1
R 7
L 4
U 4
D 1
L 5
U 2
R 9
D 7
U 8
L 8
R 4
D 1
L 1
U 7
R 8
L 3
D 2
U 8
R 1
D 5
L 1
R 7
D 6
R 2
U 9
D 2
L 5
U 4
D 9
L 7
D 9
L 2
U 9
D 5
L 7
D 6
U 5
D 9
R 3
U 8
L 7
U 1
L 3
U 3
D 1
L 6
R 9
U 2
L 7
R 9
U 5
R 2
L 3
R 4
D 9
L 4
R 9
U 4
L 10
R 9
D 9
U 10
L 2
R 4
U 4
R 9
D 2
R 1
L 4
R 7
D 3
L 6
U 1
L 9
D 6
U 10
D 1
R 10
D 9
L 6
D 10
U 3
R 10
L 8
U 9
D 1
L 1
D 10
L 1
D 5
L 9
U 3
L 4
U 4
D 1
U 3
R 7
L 3
R 3
L 3
R 8
D 9
R 4
L 6
D 7
R 10
U 6
R 2
D 2
L 3
R 9
D 9
U 7
D 2
R 6
U 10
R 8
U 5
R 5
U 10
R 6
U 7
L 7
U 7
D 4
L 9
U 2
R 7
L 8
R 4
L 1
U 9
R 8
D 4
R 5
D 4
L 1
D 10
R 8
D 10
U 9
D 3
R 1
U 10
R 1
D 10
R 1
L 6
D 3
U 8
R 4
U 9
D 8
U 3
D 2
R 3
L 5
U 4
L 3
R 4
D 6
L 9
R 1
D 9
R 2
D 11
R 8
D 5
R 8
L 2
D 2
L 7
U 11
D 10
L 6
R 2
U 9
L 10
D 4
L 5
R 7
D 4
L 1
U 3
L 9
D 7
R 4
D 10
L 5
U 9
L 10
D 5
L 11
R 11
U 8
R 11
U 2
R 7
L 10
R 2
D 8
L 2
D 8
R 11
L 6
R 3
L 2
U 2
R 2
U 3
D 3
U 5
L 8
U 9
R 10
D 1
U 4
D 8
R 3
D 11
R 4
D 4
R 7
U 6
L 11
U 11
D 8
L 5
R 2
L 11
U 7
D 5
U 5
D 9
L 2
U 3
R 10
U 1
R 1
L 11
D 3
L 5
R 2
L 10
R 4
L 1
U 1
L 4
R 5
U 2
D 6
R 11
U 8
D 5
R 5
D 3
L 2
U 7
D 10
L 11
D 10
U 11
R 8
L 2
D 9
R 9
L 11
R 10
U 3
R 4
L 5
R 12
U 5
D 5
L 6
D 11
R 8
D 12
U 6
L 10
R 9
U 1
L 12
D 1
R 8
U 9
D 9
R 6
D 3
L 1
R 3
L 8
R 6
U 12
L 1
U 8
D 7
U 5
D 12
L 4
R 11
U 9
D 12
R 8
D 2
R 7
U 8
R 10
U 3
R 4
D 4
U 9
R 7
L 9
R 7
U 8
L 9
U 6
R 4
L 11
D 11
R 6
U 2
D 1
R 2
L 2
D 11
R 5
U 1
R 1
D 3
U 2
L 3
U 12
R 10
U 12
R 9
D 11
U 9
L 2
R 7
U 5
R 7
U 9
R 3
D 4
L 9
D 4
R 12
L 3
U 12
L 9
U 3
L 11
R 7
U 11
D 2
L 11
R 2
L 12
U 10
L 6
R 8
D 6
R 12
L 7
R 4
U 5
D 10
R 8
L 11
D 4
U 1
R 9
U 12
D 3
L 10
R 11
U 1
L 5
U 11
L 7
U 1
D 13
U 10
L 12
U 9
D 8
L 5
R 4
L 1
R 2
L 7
D 1
L 11
U 9
R 5
D 12
L 4
U 7
L 6
R 7
U 1
L 7
U 2
D 4
R 4
D 7
L 3
D 9
U 3
D 3
U 12
R 2
L 12
R 9
L 8
D 10
U 1
R 11
L 13
U 1
D 3
U 12
L 3
R 7
L 7
D 7
U 7
D 7
U 10
D 1
L 7
D 11
R 3
D 6
R 9
D 5
U 12
D 6
R 8
D 3
R 7
L 6
D 10
U 8
R 9
D 4
R 9
D 2
U 4
R 4
U 7
L 12
R 2
D 10
U 13
R 12
L 12
D 1
R 11
L 2
U 13
L 12
D 7
L 2
U 4
L 4
D 8
L 9
R 3
D 4
L 9
U 9
L 9
R 10
L 4
R 4
U 10
L 11
D 8
U 8
L 13
R 1
L 8
U 13
L 9
U 1
R 13
U 7
L 3
R 8
L 1
D 5
R 7
U 8
D 5
L 12
R 11
U 11
D 10
U 5
R 6
D 11
R 1
D 1
R 9
L 8
D 4
L 11
U 9
D 4
U 3
D 13
U 13
L 6
D 6
R 11
L 9
U 3
R 7
D 9
R 5
L 9
D 14
R 8
L 14
R 6
L 6
U 6
R 7
L 11
R 1
L 6
D 10
R 1
D 14
R 12
U 4
R 2
L 9
R 14
L 3
D 9
U 10
R 11
L 5
R 14
U 3
D 8
R 9
L 13
U 4
L 2
R 4
D 6
L 13
D 4
R 2
L 2
D 10
L 10
R 4
D 2
R 2
U 6
D 7
U 12
R 5
U 13
L 6
U 12
L 3
D 11
R 3
L 7
U 11
D 4
L 13
U 14
R 10
D 12
U 2
L 1
U 12
D 6
U 2
R 12
L 3
D 9
U 9
R 14
L 12
R 5
L 11
R 11
L 5
R 2
L 4
D 8
U 3
R 4
D 12
R 10
L 10
D 10
U 10
R 9
L 14
R 3
L 1
D 1
R 15
D 15
R 12
L 15
D 12
L 10
R 3
U 14
D 4
U 7
R 11
L 10
U 4
D 15
L 3
U 1
R 2
L 15
U 6
L 6
D 3
L 14
D 12
U 1
L 15
R 13
U 7
D 6
R 11
U 7
L 2
D 11
L 1
R 7
D 1
L 4
R 11
U 5
L 4
R 13
U 1
D 4
L 6
R 10
L 15
U 7
D 9
L 10
R 8
U 10
D 8
L 14
D 15
R 14
U 10
D 4
U 6
D 2
R 6
L 6
D 4
U 12
L 3
R 6
U 9
R 3
U 11
R 3
U 15
D 1
U 2
D 3
U 11
L 3
U 2
L 14
D 3
R 9
D 5
L 10
U 7
L 6
D 8
L 8
U 8
L 14
R 9
L 14
U 10
L 8
U 5
L 2
U 4
D 5
R 2
L 1
U 14
R 3
L 4
U 9
D 7
U 14
D 11
R 9
U 5
R 8
L 5
U 3
D 8
R 8
L 11
R 7
L 3
D 16
L 11
U 7
D 6
R 5
L 4
U 9
L 12
R 9
L 10
D 13
L 3
D 13
U 6
R 14
U 2
L 5
R 4
L 15
U 9
D 5
L 6
R 7
U 10
L 3
D 5
U 8
D 12
L 11
U 14
D 12
U 2
D 9
U 11
D 5
L 5
R 10
L 14
U 1
R 8
D 5
R 6
U 6
L 3
U 11
L 8
R 3
U 5
L 1
R 16
D 10
U 12
R 11
D 2
U 4
D 15
U 16
D 2
L 9
R 10
L 3
U 8
R 13
U 11
D 12
U 15
D 1
L 14
R 3
U 13
D 7
R 15
L 3
R 1
U 7
R 6
D 12
L 2
R 13
D 3
R 6
D 10
U 2
R 4
D 12
L 7
R 7
L 8
R 14
L 15
D 8
L 6
U 14
L 16
U 10
D 7
R 6
D 12
R 16
U 11
R 2
U 10
L 1
R 6
U 14
D 13
U 7
L 10
D 4
L 7
R 11
U 17
D 6
U 6
R 6
U 12
L 16
U 5
R 15
L 17
D 13
U 12
L 1
D 7
L 13
R 7
U 2
L 5
U 12
R 10
U 7
R 11
U 17
D 15
U 15
L 10
D 3
L 15
U 8
R 8
D 10
L 9
U 6
R 9
L 1
U 5
R 6
L 11
D 17
L 7
U 3
D 17
R 17
U 8
L 15
R 3
D 2
U 17
L 1
R 13
U 13
L 10
R 2
D 12
L 12
R 13
L 14
R 16
D 12
R 4
U 14
L 15
R 10
D 7
R 12
U 6
L 8
U 7
R 1
D 3
R 3
L 11
D 2
R 15
U 17
L 13
U 17
D 4
U 11
L 17
D 12
R 3
L 12
U 8
D 2
L 14
U 16
D 6
U 7
L 12
R 17
L 7
D 1
L 16
D 16
R 17
D 5
U 16
D 2
L 13
U 9
D 13
R 3
U 1
D 12
R 4
D 11
L 8
D 8
R 13
D 16
R 1
D 10
R 18
U 6
D 4
U 17
R 12
L 14
U 5
L 15
U 18
R 4
D 17
L 4
R 18
U 18
D 4
L 1
U 4
L 2
U 17
R 16
L 7
U 10
R 11
U 9
R 11
L 16
U 3
R 3
L 18
U 8
R 1
U 1
L 5
U 5
D 7
L 1
R 2
U 16
R 17
D 4
U 16
L 12
R 3
L 16
D 5
U 5
R 18
L 7
U 1
L 7
U 16
R 14
L 4
R 13
L 3
U 4
L 11
U 3
L 12
U 16
L 14
U 3
L 9
R 18
D 8
L 15
R 10
D 2
L 13
D 11
U 4
L 13
D 7
L 12
U 7
D 17
U 9
D 5
L 10
R 2
D 7
L 14
U 10
D 17
L 3
R 17
U 16
D 13
R 13
U 14
R 9
L 3
U 14
L 7
U 4
D 1
R 18
U 11
D 9
U 8
R 15
L 5
D 9
L 2
D 18
U 12
D 3
U 14
D 9
U 13
R 16
U 8
R 16
U 4
L 8
D 14
R 15
D 6
R 17
U 6
D 1
L 2
U 9
D 15
L 7
D 3
R 1
L 1
R 17
D 12
R 19
U 4
R 19
L 2
D 17
U 11
D 1
L 9
R 18
L 7
D 13
U 6
D 16
L 6
R 13
U 12
R 1
L 2
U 8
L 16
R 10
D 15
R 5
L 1
U 5
R 18
U 1
R 4
U 14
R 3
L 4
U 13
D 14
L 10
D 7
U 3
R 17
L 19
R 1
D 12
L 9
U 19
D 19
L 5
R 10
L 14
U 15
D 19
U 18
D 14
R 11
U 8
R 2
U 16
L 17
D 6
L 1
D 10
R 18
U 5
R 14
U 10
D 6
L 17
D 6
U 7
R 14
L 1
U 3
D 3
R 18
D 1
L 6
D 18
L 2
R 10
L 9
R 10
L 14
R 15
U 10
""";
#endregion
}