-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRunner.cs
118 lines (92 loc) · 4.05 KB
/
Runner.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
using System.ComponentModel;
using System.Diagnostics;
class Runner
{
private record struct Puzzle(PuzzleSolution solution, string input);
private static string GetDescription(System.Reflection.MemberInfo info)
{
return ((DescriptionAttribute)Attribute.GetCustomAttribute(info, typeof(DescriptionAttribute))!).Description;
}
private static void AddPuzzle(List<Puzzle> list, int day, int year, string inputType)
{
var puzzleName = $"Puzzle{day:D2}";
var puzzleClassName = $"Advent{year}.{puzzleName}";
list.Add(new Puzzle(
(PuzzleSolution)(Activator.CreateInstance(Type.GetType(puzzleClassName)
?? throw new ArgumentException($"Solver for day {day} and year {year} is not loaded in this assembly."))
?? throw new ArgumentException("Impossible to instantiate solver for day {day} and year {year}.")),
File.ReadAllText(Path.Combine(puzzleName, inputType == "real" ? "input.txt" : "example.txt"))
));
}
private static List<Puzzle> LoadPuzzles(int year, int day = 0, string inputType = "real")
{
var puzzles = new List<Puzzle>();
if (day != 0)
{
AddPuzzle(puzzles, day, year, inputType);
return puzzles;
}
var integerComparison = Comparer<string>.Create(
(string a, string b) =>
Comparer<int>.Default.Compare(int.Parse(a.AsSpan().Slice(8)), int.Parse(b.AsSpan().Slice(8)))
);
foreach (string puzzleDirectory in Directory.GetDirectories(".", "Puzzle*", SearchOption.TopDirectoryOnly).Order(integerComparison))
{
int foundPuzzleDay = int.Parse(puzzleDirectory.AsSpan().Slice(8));
AddPuzzle(puzzles, foundPuzzleDay, year, inputType);
}
return puzzles;
}
private static void Run(int year, int day = 0, string inputType = "real")
{
var puzzles = LoadPuzzles(year, day, inputType);
foreach ((PuzzleSolution solver, string input) in puzzles)
{
var puzzleName = solver.GetType().FullName;
var puzzleDescription = GetDescription(solver.GetType());
Console.WriteLine($"Running {puzzleName}: {puzzleDescription}.");
var watch = Stopwatch.StartNew();
solver.Setup(input);
watch.Stop();
Console.WriteLine($"Setup completed. Elapsed: {watch.ElapsedMilliseconds} ms.");
var partOneDescription = GetDescription(solver.GetType().GetMethod("SolvePartOne")!);
Console.WriteLine($"Part one. {partOneDescription}");
watch = Stopwatch.StartNew();
var result = solver.SolvePartOne();
watch.Stop();
Console.WriteLine($"Result: \"{result}\". Elapsed: {watch.ElapsedMilliseconds} ms.");
var partTwoDescription = GetDescription(solver.GetType().GetMethod("SolvePartTwo")!);
Console.WriteLine($"Part two. {partTwoDescription}");
watch = Stopwatch.StartNew();
result = solver.SolvePartTwo();
watch.Stop();
Console.WriteLine($"Result: \"{result}\". Elapsed: {watch.ElapsedMilliseconds} ms.");
Console.WriteLine("");
}
}
static void Main(string[] args)
{
int day = 0;
int year = 2023;
string inputType = "real";
if (args.Length > 1 && int.TryParse(args[1], out int newYear))
{
year = newYear;
Console.WriteLine($"Year {year} specified through command line.");
}
if (args.Length > 0 && int.TryParse(args[0], out day))
{
Console.WriteLine($"Day {day} specified through command line.");
} else
{
Console.WriteLine($"No day specified through command line. Running all days for year {year}.");
}
if (args.Length > 2 && args[2] == "example")
{
Console.WriteLine("Running example input.");
inputType = "example";
}
Console.WriteLine();
Run(year, day, inputType);
}
}