From 3b13aa858546143b36aae4fcd0477dd049ed0653 Mon Sep 17 00:00:00 2001 From: Amatsugu Date: Fri, 2 Dec 2022 22:10:51 -0500 Subject: [PATCH] Updates to problem runner --- AdventOfCode/AdventOfCode.csproj | 15 +-- .../Problems/AOC2022/Day0/TestProblem.cs | 12 +-- .../Problems/AOC2022/Day1/CalorieCounting.cs | 14 +-- .../Problems/AOC2023/Day0/TestProblem.cs | 12 +-- AdventOfCode/Program.cs | 6 -- AdventOfCode/Runner/AOCRunner.cs | 102 ++++++++++++++++-- AdventOfCode/Runner/IProblemBase.cs | 27 +++-- 7 files changed, 135 insertions(+), 53 deletions(-) diff --git a/AdventOfCode/AdventOfCode.csproj b/AdventOfCode/AdventOfCode.csproj index e15cd69..3c23274 100644 --- a/AdventOfCode/AdventOfCode.csproj +++ b/AdventOfCode/AdventOfCode.csproj @@ -1,4 +1,4 @@ - + Exe @@ -7,22 +7,11 @@ enable - - - - - - + PreserveNewest - - PreserveNewest - - - Always - diff --git a/AdventOfCode/Problems/AOC2022/Day0/TestProblem.cs b/AdventOfCode/Problems/AOC2022/Day0/TestProblem.cs index f1166dc..923797f 100644 --- a/AdventOfCode/Problems/AOC2022/Day0/TestProblem.cs +++ b/AdventOfCode/Problems/AOC2022/Day0/TestProblem.cs @@ -3,30 +3,30 @@ using AdventOfCode.Runner.Attributes; namespace AdventOfCode.Problems.AOC2022.Day0; [ProblemInfo("2022", 0, "Fancy Test")] -public class TestProblem : IProblem +public class TestProblem : Problem { - public void LoadInput() + public override void LoadInput() { Thread.Sleep(1000); } - public void CalculatePart1() + public override void CalculatePart1() { Thread.Sleep(1000); } - public void CalculatePart2() + public override void CalculatePart2() { Thread.Sleep(1000); } - public void PrintPart1() + public override void PrintPart1() { Console.WriteLine("Result"); } - public void PrintPart2() + public override void PrintPart2() { Console.WriteLine("Result 2"); } diff --git a/AdventOfCode/Problems/AOC2022/Day1/CalorieCounting.cs b/AdventOfCode/Problems/AOC2022/Day1/CalorieCounting.cs index c21835f..64da24d 100644 --- a/AdventOfCode/Problems/AOC2022/Day1/CalorieCounting.cs +++ b/AdventOfCode/Problems/AOC2022/Day1/CalorieCounting.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace AdventOfCode.Problems.AOC2022.Day1; [ProblemInfo("2022", 1, "Calorie Counting")] -internal class CalorieCounting : IProblem +internal class CalorieCounting : Problem { public List> FlaresFood { get; set; } @@ -23,9 +23,9 @@ internal class CalorieCounting : IProblem }; } - public void LoadInput() + public override void LoadInput() { - var lines = File.ReadAllLines("Problems/AOC2022/Day1/input.txt"); + var lines = File.ReadAllLines(GetInputFile("input.txt")); var c = 0; foreach (var calorie in lines) { @@ -38,14 +38,14 @@ internal class CalorieCounting : IProblem FlaresFood[c].Add(int.Parse(calorie)); } } - public void CalculatePart1() + public override void CalculatePart1() { _mostestElf = FlaresFood .Select((x, idx) => (sum: x.Sum(), idx)) .MaxBy(x => x.sum); } - public void CalculatePart2() + public override void CalculatePart2() { _mostestElves = FlaresFood .Select((x, idx) => (sum: x.Sum(), idx)) @@ -54,7 +54,7 @@ internal class CalorieCounting : IProblem } - public void PrintPart1() + public override void PrintPart1() { if (_mostestElf == null) { @@ -64,7 +64,7 @@ internal class CalorieCounting : IProblem Console.WriteLine($"Mostest: {_mostestElf}"); } - public void PrintPart2() + public override void PrintPart2() { if(_mostestElves == null) { diff --git a/AdventOfCode/Problems/AOC2023/Day0/TestProblem.cs b/AdventOfCode/Problems/AOC2023/Day0/TestProblem.cs index b4c886d..215fd17 100644 --- a/AdventOfCode/Problems/AOC2023/Day0/TestProblem.cs +++ b/AdventOfCode/Problems/AOC2023/Day0/TestProblem.cs @@ -3,30 +3,30 @@ using AdventOfCode.Runner.Attributes; namespace AdventOfCode.Problems.AOC2023.Day0; [ProblemInfo("2023", 0, "Test")] -public class TestProblem : IProblem +public class TestProblem : Problem { - public void LoadInput() + public override void LoadInput() { Thread.Sleep(1000); } - public void CalculatePart1() + public override void CalculatePart1() { Thread.Sleep(1000); } - public void CalculatePart2() + public override void CalculatePart2() { Thread.Sleep(1000); } - public void PrintPart1() + public override void PrintPart1() { Console.WriteLine("Result"); } - public void PrintPart2() + public override void PrintPart2() { Console.WriteLine("Result 2"); } diff --git a/AdventOfCode/Program.cs b/AdventOfCode/Program.cs index 3124cea..781e2ca 100644 --- a/AdventOfCode/Program.cs +++ b/AdventOfCode/Program.cs @@ -10,11 +10,5 @@ internal class Program { var runner = new AOCRunner(); runner.RenderMenu(); - var cc = new RockPaperScissors(); - cc.LoadInput(); - cc.CalculatePart1(); - cc.PrintPart1(); - cc.CalculatePart2(); - cc.PrintPart2(); } } diff --git a/AdventOfCode/Runner/AOCRunner.cs b/AdventOfCode/Runner/AOCRunner.cs index 48fbb0c..41acafa 100644 --- a/AdventOfCode/Runner/AOCRunner.cs +++ b/AdventOfCode/Runner/AOCRunner.cs @@ -1,5 +1,6 @@ using AdventOfCode.Runner.Attributes; +using System.Diagnostics; using System.Reflection; namespace AdventOfCode.Runner; @@ -16,7 +17,7 @@ public class AOCRunner private void FindProblemClasses() { - var types = Assembly.GetExecutingAssembly().DefinedTypes.Where(t => t.IsAssignableTo(typeof(IProblem)) && !t.IsInterface); + var types = Assembly.GetExecutingAssembly().DefinedTypes.Where(t => t.IsAssignableTo(typeof(Problem)) && !t.IsInterface); if (types == null) return; foreach (var type in types) @@ -37,21 +38,110 @@ public class AOCRunner { var years = _loadedProblems.Keys.OrderByDescending(k => k); - Console.WriteLine("Available Problems:"); - foreach (var year in years) - RenderYearMenu(year); + var defaultYear = DateTime.Now.Year.ToString(); + + Console.WriteLine($"Select a Year: (blank is {defaultYear})"); + var inputYear = Console.ReadLine(); + if (string.IsNullOrWhiteSpace(inputYear)) + inputYear = defaultYear; + + RenderYearMenu(defaultYear); } private void RenderYearMenu(string year) { + if(!_loadedProblems.ContainsKey(year)) + { + Console.WriteLine($"No problems for {year} exist"); + return; + } Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($"{year}:"); Console.ForegroundColor = ConsoleColor.Gray; var days = _loadedProblems[year]; for (int i = 0; i < days.Count; i++) { - var (info, type) = days[i]; - Console.WriteLine($"\tDay {info.Day} - {info.Name}"); + var (info, _) = days[i]; + Console.ForegroundColor = ConsoleColor.Magenta; + Console.Write($"\t [{i}]"); + Console.ForegroundColor = ConsoleColor.Gray; + Console.WriteLine($" - Day {info.Day} - {info.Name}"); + } + + Console.WriteLine(); + var defaultDay = DateTime.Now.Day; + + Console.WriteLine($"Select Day Index: (blank is {defaultDay})"); + var inputDay = Console.ReadLine(); + + if(!int.TryParse(inputDay, out var parsedDay)) + parsedDay = defaultDay; + + RunDay(year, parsedDay); + } + + private void RunDay(string year, int dayIndex) + { + var yearList = _loadedProblems[year]; + if (yearList.Count <= dayIndex || dayIndex < 0) + Console.WriteLine($"No problem exists for day index {dayIndex}"); + + Console.Clear(); + var (info, problemType) = yearList[dayIndex]; + + Console.WriteLine($"Problem: \t{info.Name}"); + Console.WriteLine($"\t\t{info.Year} - {info.Day}"); + + + var problem = Activator.CreateInstance(problemType) as Problem; + if(problem == null ) { + Console.WriteLine("Failed to create problem isntance"); + return; + } + Console.WriteLine("Loading Input data..."); + problem.LoadInput(); + + Console.WriteLine(); + + RunPart("Calculating Part 1", problem.CalculatePart1); + RunPart("Calculating Part 2", problem.CalculatePart2); + + Console.WriteLine(); + Console.WriteLine("Printing Results:"); + + Console.WriteLine("---- Part 1 ----"); + problem.PrintPart1(); + Console.Write("\n\n"); + Console.WriteLine("---- Part 2 ----"); + problem.PrintPart2(); + Console.Write("\n\n"); + } + + private static void RunPart(string name, Action action) + { + Console.ForegroundColor = ConsoleColor.Gray; + var sw = new Stopwatch(); + Console.Write($"{name}... "); + try + { + sw.Start(); + action(); + sw.Stop(); + Console.ForegroundColor = ConsoleColor.Green; + Console.Write("Done in "); + Console.ForegroundColor = ConsoleColor.Cyan; + Console.WriteLine($"{sw.ElapsedMilliseconds}ms"); + } + catch (Exception e) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Failed"); + Console.WriteLine(e); + } + finally + { + sw.Stop(); + Console.ForegroundColor = ConsoleColor.Gray; } } } \ No newline at end of file diff --git a/AdventOfCode/Runner/IProblemBase.cs b/AdventOfCode/Runner/IProblemBase.cs index cc57198..9d121b0 100644 --- a/AdventOfCode/Runner/IProblemBase.cs +++ b/AdventOfCode/Runner/IProblemBase.cs @@ -1,18 +1,27 @@ -using System; +using AdventOfCode.Runner.Attributes; + +using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; namespace AdventOfCode.Runner; -public interface IProblem +public abstract class Problem { - void LoadInput(); + public abstract void LoadInput(); + public abstract void CalculatePart1(); + public abstract void PrintPart1(); + public abstract void CalculatePart2(); + public abstract void PrintPart2(); - void CalculatePart1(); - - void PrintPart1(); - - void CalculatePart2(); - void PrintPart2(); + protected string GetInputFile(string filename) + { + var info = this.GetType().GetCustomAttribute(); + if (info == null) + return filename; + + return Path.Combine($"Problems/AOC{info.Year}/Day{info.Day}", filename); + } } \ No newline at end of file