-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay06.cs
156 lines (126 loc) · 3.25 KB
/
Day06.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
namespace advent_of_code_csharp_2024.Day06;
public record Position(int X, int Y);
public class Cells
{
private readonly char[][] _cells;
public char[] this[int row]
{
get
{
return _cells[0];
}
}
public Cells(char[][] cells)
{
_cells = cells;
}
public static Cells FromText(string lines)
{
return new Cells(LoadCells(lines));
}
public static Cells FromLines(IEnumerable<string> lines)
{
return new Cells(LoadCells(lines));
}
public Position GetStartPosition()
{
var x = _cells
.SelectMany((line, y) => line.Select((cell, x) => (new Position(x, y), cell)))
.First(_ => _.cell == '^');
return x.Item1;
}
private static char[][] LoadCells(string text)
{
return LoadCells(text.Split(Environment.NewLine));
}
private static char[][] LoadCells(IEnumerable<string> lines)
{
return lines
.Select(line => line.ToCharArray().Where(c => ".#^".Contains(c)).ToArray())
.Where(line => line.Length > 0)
.ToArray();
}
public char GetCell(Position p)
{
return _cells[p.Y][p.X];
}
internal bool IsObstruction(Position p)
{
if (IsOutsideOfBounds(p))
{
return false;
}
return GetCell(p) == '#';
}
internal bool IsOutsideOfBounds(Position p)
{
return
p.X < 0 ||
p.X >= _cells[0].Length ||
p.Y < 0 ||
p.Y >= _cells.Length;
}
internal void SetTrace(Position position)
{
_cells[position.Y][position.X] = 'X';
}
internal int VisitCount()
{
return _cells
.SelectMany(row => row)
.Count(cell => cell == 'X');
}
}
public enum Direction { Up, Right, Down, Left };
public class Guard
{
public Position Position { get; private set; }
public Direction Direction { get; private set; }
public Guard(Position position, Direction direction)
{
Position = position;
Direction = direction;
}
internal bool Move(Cells cells)
{
Position nextPosition;
for (nextPosition = GetNextPosition(); cells.IsObstruction(nextPosition); Turn(), nextPosition = GetNextPosition())
{
}
if (cells.IsOutsideOfBounds(nextPosition))
{
return false;
}
Position = nextPosition;
// Console.WriteLine($"Direction: {Direction} {Position}");
cells.SetTrace(Position);
return true;
}
private void Turn()
{
Direction = Direction switch
{
Direction.Up => Direction.Right,
Direction.Right => Direction.Down,
Direction.Down => Direction.Left,
Direction.Left => Direction.Up,
_ => throw new Exception($"Unknown direction: {Direction}")
};
}
private Position GetNextPosition()
{
return Direction switch
{
Direction.Up => new Position(Position.X, Position.Y - 1),
Direction.Right => new Position(Position.X + 1, Position.Y),
Direction.Down => new Position(Position.X, Position.Y + 1),
Direction.Left => new Position(Position.X - 1, Position.Y),
_ => throw new Exception($"Unknown direction: {Direction}")
};
}
public void DoRun(Cells cells)
{
cells.SetTrace(Position);
do { } while (Move(cells));
}
}