-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day16.cs
105 lines (91 loc) · 4 KB
/
Day16.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
namespace AoC2023;
public class Day16 : IDay<IEnumerable<string>, long>
{
public static long SolvePart1(IEnumerable<string> input) =>
GetEnergizedCount((0, 0), input.ToArray(), Direction.Right);
public static int GetEnergizedCount((int, int) pos, string[] grid, Direction direction)
{
Queue<((int, int), Direction)> queue = [];
HashSet<((int, int), Direction)> visited = [];
queue.Enqueue((pos, direction));
while (queue.Any())
{
var ((currR, currC), dir) = queue.Dequeue();
if (IsOutsideGrid((currR, currC), grid))
{
continue;
}
visited.Add(((currR, currC), dir));
var currTile = grid[currR][currC];
foreach (var item in FindNextTilesToVisit(currTile, currR, currC, dir))
{
if (visited.Contains(item))
{
continue;
}
queue.Enqueue(item);
}
}
return visited.Select((item) => item.Item1).ToHashSet().Count();
}
public enum Direction
{
Right,
Left,
Top,
Bottom
}
public static IEnumerable<((int, int), Direction)> FindNextTilesToVisit(
char currTile,
int currR,
int currC,
Direction dir
) =>
(dir, currTile) switch
{
(Direction.Right or Direction.Left, '|')
=> [((currR - 1, currC), Direction.Top), ((currR + 1, currC), Direction.Bottom)],
(Direction.Top or Direction.Bottom, '-')
=> [((currR, currC + 1), Direction.Right), ((currR, currC - 1), Direction.Left)],
(Direction.Left, '-') => [((currR, currC - 1), Direction.Left)],
(Direction.Right, '-') => [((currR, currC + 1), Direction.Right)],
(Direction.Top, '|') => [((currR - 1, currC), Direction.Top)],
(Direction.Bottom, '|') => [((currR + 1, currC), Direction.Bottom)],
(Direction.Top, '/') => [((currR, currC + 1), Direction.Right)],
(Direction.Top, '\\') => [((currR, currC - 1), Direction.Left)],
(Direction.Bottom, '/') => [((currR, currC - 1), Direction.Left)],
(Direction.Bottom, '\\') => [((currR, currC + 1), Direction.Right)],
(Direction.Right, '/') => [((currR - 1, currC), Direction.Top)],
(Direction.Right, '\\') => [((currR + 1, currC), Direction.Bottom)],
(Direction.Left, '/') => [((currR + 1, currC), Direction.Bottom)],
(Direction.Left, '\\') => [((currR - 1, currC), Direction.Top)],
(Direction.Left, '.') => [((currR, currC - 1), Direction.Left)],
(Direction.Right, '.') => [((currR, currC + 1), Direction.Right)],
(Direction.Top, '.') => [((currR - 1, currC), Direction.Top)],
(Direction.Bottom, '.') => [((currR + 1, currC), Direction.Bottom)],
(_, _) => throw new Exception($"OOPS: ({currR}, {currC}) : [{currTile}] : {dir}")
};
public static bool IsOutsideGrid((int, int) pos, string[] grid)
{
var (r, c) = pos;
var maxR = grid.Length - 1;
var maxC = grid[0].Length - 1;
return r < 0 || r > maxR || c < 0 || c > maxC;
}
public static long SolvePart2(IEnumerable<string> input)
{
var grid = input.ToArray();
var rowsToTry = Enumerable.Range(0, grid.Length);
var colsToTry = Enumerable.Range(0, grid[0].Length);
var maxC = grid[0].Length - 1;
var maxR = grid.Length - 1;
IEnumerable<int> PossibleEnergizedCounts =
[
..rowsToTry.Select((r) => GetEnergizedCount((r, 0), grid, Direction.Right)),
..rowsToTry.Select((r) => GetEnergizedCount((r, maxC), grid, Direction.Left)),
..colsToTry.Select((c) => GetEnergizedCount((0, c), grid, Direction.Bottom)),
..colsToTry.Select((c) => GetEnergizedCount((maxR, c), grid, Direction.Top))
];
return PossibleEnergizedCounts.Max();
}
}