-
Notifications
You must be signed in to change notification settings - Fork 1
/
Program.cs
72 lines (55 loc) · 1.65 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
using AdventOfCode.Common;
/*
maxTime = 15
distance > 40
distance = (maxTime - wait) * wait
wait > 0
wait < maxTime
distance = (15 - wait) * wait
0 = -wait^2 + maxTime * wait - distance
a = -1
b = m
c = -d
x = (-maxTime +/- sqrt(maxTime^2 - 8 * distance)) / -4
*/
var lines = Resources.GetInputFileLines();
List<List<int>> numbers = lines
.Select(l => l.ParseNumbersOut())
.ToList();
List<long> unkernedNumbers = lines
.Select(s => s.Replace(" ", null))
.Select(s => s.ParseLongNumbersOut().First())
.ToList();
long part1 = numbers
.First()
.Zip(numbers.Last())
.Select(p => GetNumberOfWays(p.First, p.Second))
.Multiply();
long part2 = GetNumberOfWays(unkernedNumbers.First(), unkernedNumbers.Last());
Console.WriteLine($"Part 1: {part1}");
Console.WriteLine($"Part 2: {part2}");
static long GetNumberOfWays(long maxTime, long maxDistance)
{
var (min, max) = Solve(maxTime, maxDistance);
min = Math.Max(1, min);
max = Math.Min(max, maxTime - 1);
var ways = (int)(Math.Floor(max) - Math.Ceiling(min)) + 1;
// Correction for boundaries
if (GetDistance(maxTime, (int)Math.Ceiling(min)) <= maxDistance)
{
ways--;
}
if (GetDistance(maxTime, (int)Math.Floor(max)) <= maxDistance)
{
ways--;
}
return ways;
}
static long GetDistance(long maxTime, long waitTime) => (maxTime - waitTime) * waitTime;
static (double, double) Solve(long maxTime, long maxDistance)
{
var root = Math.Sqrt(maxTime * maxTime - 4 * maxDistance);
double Calc(double r) => (- maxTime + r) / -2;
var (min, max) = (Calc(root), Calc(-root));
return min < max ? (min, max) : (max, min);
}