-
Notifications
You must be signed in to change notification settings - Fork 1
/
Program.cs
77 lines (60 loc) · 1.89 KB
/
Program.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
using AdventOfCode.Common;
using Coor = AdventOfCode.Common.Coor<int>;
var input = Resources.GetInputFileLines().First();
var coordinates = input
.Substring("target area: x=".Length)
.Split(", y=")
.SelectMany(s => s.Split(".."))
.Select(int.Parse)
.ToArray();
Coor from = new(X: Math.Min(coordinates[0], coordinates[1]), Y: Math.Max(coordinates[2], coordinates[3]));
Coor to = new(X: Math.Max(coordinates[0], coordinates[1]), Y: Math.Min(coordinates[2], coordinates[3]));
// Minimal speed to reach the nearest part of the target (gives us the most time to fire up)
var minXVelocity = (int)Math.Ceiling((Math.Sqrt(1 + from.X * 8) - 1) / 2);
bool IsHit(Coor speed, out int maxHeight)
{
var position = new Coor(0, 0);
maxHeight = 0;
while (position.X < to.X && position.Y > to.Y)
{
position += speed;
speed = speed with
{
X = speed.X > 0 ? speed.X - 1 : 0,
Y = speed.Y - 1,
};
maxHeight = Math.Max(maxHeight, position.Y);
if (position.X >= from.X && position.Y <= from.Y && position.X <= to.X && position.Y >= to.Y)
{
return true;
}
}
return false;
}
int GetMaxHeight()
{
int maxHeight = 0;
for (int yVelocity = 0; yVelocity <= -to.Y; yVelocity++)
{
if (IsHit(new Coor(X: minXVelocity, Y: yVelocity), out var max))
{
maxHeight = Math.Max(maxHeight, max);
}
}
return maxHeight;
}
int GetPossibleVelocityCount()
{
int hitCount = 0;
for (int xVelocity = minXVelocity; xVelocity <= to.X; xVelocity++)
for (int yVelocity = to.Y; yVelocity <= -to.Y; yVelocity++)
{
if (IsHit(new Coor(X: xVelocity, Y: yVelocity), out _))
{
hitCount++;
}
}
return hitCount;
}
Console.WriteLine($"Part 1: {GetMaxHeight()}");
Console.WriteLine($"Part 2: {GetPossibleVelocityCount()}");