feat: solved day 16 part 1
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
namespace ReindeerMaze.Tests;
|
||||
|
||||
public class PuzzleSolverTests
|
||||
{
|
||||
[Test]
|
||||
[MethodDataSource(nameof(SolveTestCases))]
|
||||
public async Task Solve_WhenCalledWithInput_ItShouldReturnExpectedValue(SolveTestCase testCase)
|
||||
{
|
||||
var result = PuzzleSolver.Solve(testCase.Input);
|
||||
|
||||
await Assert.That(result).IsEqualTo(testCase.ExpectedValue);
|
||||
}
|
||||
|
||||
public static IEnumerable<Func<SolveTestCase>> SolveTestCases()
|
||||
{
|
||||
yield return () => new(
|
||||
[
|
||||
"###############",
|
||||
"#.......#....E#",
|
||||
"#.#.###.#.###.#",
|
||||
"#.....#.#...#.#",
|
||||
"#.###.#####.#.#",
|
||||
"#.#.#.......#.#",
|
||||
"#.#.#####.###.#",
|
||||
"#...........#.#",
|
||||
"###.#.#####.#.#",
|
||||
"#...#.....#.#.#",
|
||||
"#.#.#.###.#.#.#",
|
||||
"#.....#...#.#.#",
|
||||
"#.###.#.#.#.#.#",
|
||||
"#S..#.....#...#",
|
||||
"###############",
|
||||
],
|
||||
7036
|
||||
);
|
||||
|
||||
yield return () => new(
|
||||
[
|
||||
"#################",
|
||||
"#...#...#...#..E#",
|
||||
"#.#.#.#.#.#.#.#.#",
|
||||
"#.#.#.#...#...#.#",
|
||||
"#.#.#.#.###.#.#.#",
|
||||
"#...#.#.#.....#.#",
|
||||
"#.#.#.#.#.#####.#",
|
||||
"#.#...#.#.#.....#",
|
||||
"#.#.#####.#.###.#",
|
||||
"#.#.#.......#...#",
|
||||
"#.#.###.#####.###",
|
||||
"#.#.#...#.....#.#",
|
||||
"#.#.#.#####.###.#",
|
||||
"#.#.#.........#.#",
|
||||
"#.#.#.#########.#",
|
||||
"#S#.............#",
|
||||
"#################",
|
||||
],
|
||||
11048
|
||||
);
|
||||
}
|
||||
|
||||
public record SolveTestCase(string[] Input, int ExpectedValue);
|
||||
}
|
||||
+97
-14
@@ -1,24 +1,107 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
if (args.Length is 0)
|
||||
{
|
||||
Console.WriteLine("Please provide a path to the input file.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (File.Exists(args[0]) is false)
|
||||
{
|
||||
Console.WriteLine("The provided file does not exist.");
|
||||
return;
|
||||
}
|
||||
// if (args.Length is 0)
|
||||
// {
|
||||
// Console.WriteLine("Please provide a path to the input file.");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (File.Exists(args[0]) is false)
|
||||
// {
|
||||
// Console.WriteLine("The provided file does not exist.");
|
||||
// return;
|
||||
// }
|
||||
|
||||
var isPart2 = args.Length is 2 && args[1] is "part2";
|
||||
var input = await File.ReadAllLinesAsync(args[0]);
|
||||
var input = await File.ReadAllLinesAsync(Path.Combine(AppContext.BaseDirectory, "INPUT.txt"));
|
||||
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
|
||||
// TODO: Implement solution
|
||||
var result = PuzzleSolver.Solve(input);
|
||||
|
||||
stopwatch.Stop();
|
||||
Console.WriteLine($". ({stopwatch.ElapsedMilliseconds}ms)");
|
||||
Console.WriteLine($"The lowest score a Reindeer could get is {result}. ({stopwatch.ElapsedMilliseconds}ms)");
|
||||
|
||||
static class PuzzleSolver
|
||||
{
|
||||
public static int Solve(string[] input)
|
||||
{
|
||||
List<(int Xd, int Yd)> directions = [
|
||||
(1, 0),
|
||||
(0, 1),
|
||||
(-1, 0),
|
||||
(0, -1),
|
||||
];
|
||||
|
||||
var rows = input.Length;
|
||||
var columns = input[0].Length;
|
||||
|
||||
(int X, int Y) start = (-1, -1);
|
||||
(int X, int Y) end = (-1, -1);
|
||||
|
||||
for (var row = 0; row < rows; row++)
|
||||
{
|
||||
for (var column = 0; column < columns; column++)
|
||||
{
|
||||
var currentValue = input[row][column];
|
||||
|
||||
switch (currentValue)
|
||||
{
|
||||
case 'S':
|
||||
start = (column, row);
|
||||
break;
|
||||
case 'E':
|
||||
end = (column, row);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var queue = new PriorityQueue<(int X, int Y, int Direction, int Score), int>();
|
||||
var visited = new HashSet<(int X, int Y, int Direction)>();
|
||||
var initialScore = 0;
|
||||
var initialDirection = 0;
|
||||
|
||||
queue.Enqueue((start.X, start.Y, initialDirection, initialScore), initialScore);
|
||||
|
||||
while (queue.Count is not 0)
|
||||
{
|
||||
var current = queue.Dequeue();
|
||||
|
||||
var possibleVisited = (current.X, current.Y, current.Direction);
|
||||
|
||||
if (visited.Contains((possibleVisited)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
visited.Add(possibleVisited);
|
||||
|
||||
if (current.X == end.X && current.Y == end.Y)
|
||||
{
|
||||
return current.Score;
|
||||
}
|
||||
|
||||
var currentDirection = directions[current.Direction];
|
||||
var nextX = current.X + currentDirection.Xd;
|
||||
var nextY = current.Y + currentDirection.Yd;
|
||||
|
||||
if (nextX >= 0 && nextX < columns && nextY >= 0 && nextY < rows && input[nextY][nextX] != '#')
|
||||
{
|
||||
var newScoreAfterMovingForward = current.Score + 1;
|
||||
queue.Enqueue((nextX, nextY, current.Direction, newScoreAfterMovingForward), newScoreAfterMovingForward);
|
||||
}
|
||||
|
||||
var newScoreAfterTurning = current.Score + 1000;
|
||||
|
||||
var directionAfterClockWiseTurn = (current.Direction + 1) % directions.Count;
|
||||
queue.Enqueue((current.X, current.Y, directionAfterClockWiseTurn, newScoreAfterTurning), newScoreAfterTurning);
|
||||
|
||||
var directionAfterCounterClockWiseTurn = (current.Direction + 3) % directions.Count;
|
||||
queue.Enqueue((current.X, current.Y, directionAfterCounterClockWiseTurn, newScoreAfterTurning), newScoreAfterTurning);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user