As usual, for December, the Advent of Code challenge has once again started this year.
I've been trying to do doing it for quite some time now, always in C#, and always have had to type the same code:
- The parser for the input file
- The solution for the first puzzle
- The test for the example
- The test for the solution
- The solution for the second puzzle
- The test for the example
- The test for the solution
It may not be much, but it results in either an inconsistent way of solving the puzzles or in a lot of redundancy in the code for each day.
To spare some time (or at least spare some of yours), I created a small GitHub template repository so that you can quickly get started on the implementation on this year's puzzles and not on the boilerplate to do so:
pBouillon / dotnet-advent-of-code-template
Advent of Code template for .NET contenders, focus on the puzzle, let it handle the rest
Dotnet Advent of Code
Advent of Code template for .NET contenders, focus on the puzzle, let it take care the rest
After gaining yours, consider leaving a small ⭐ to this project too!
Advantages
In order to solve your puzzle, you might need the debugger from time to time, especially as the puzzles become harder.
This template is built around test projects, in order to take advatage of the debugging possibilities and TDD if you want to.
Here are also a bunch of features offered by the template:
- Retrieval of the puzzle input localy or remotely
- Testing of your modelization if you would like to
- Testing of the puzzle examples
- Conditionnaly skip the tests of a puzzle if wanted
Usage
This template exposes two classes: a Solver
and a TestEngine
.
The .NET CI is also preconfigured to ensure that all your tests are valid.
To get started with a…
It also comes with the GitHub Action's CI preconfigured and a demo project if you need some guidance.
Usage
It's usage is fairly simple:
- For your logic, inherit from
Solver
- To test your logic against the example and find your solution, inherit from
TestEngine
The Solver
The solver is the place where you can specify where your input is, how and to what you want it to be parsed, and the logic to solve the first and second part of the puzzle.
Let's see its usage with an example:
If the first part of the puzzle is "Given a list of integers, find the greatest one" and the second one "Now find the sum of them", we can do the following:
public class Solver : Solver<int[], int>
{
protected override string InputPath => "input.txt";
public override int PartOne(int[] input)
=> input.Max();
public override int PartTwo(int[] input)
=> input.Sum();
public override int[] ReadInput(string inputPath)
=> File
.ReadAllLines(inputPath)
.Select(int.Parse)
.ToArray();
}
The TestEngine
The test engine is the class that will allow you to check if your solutions are right.
For each part, you will be asked to specify what your example is and what solution you are expecting.
Of course, the solution is unknown at first and making this test fail will show you your solution.
For our example, we may have written the following:
public class SolverTest : TestEngine<Solver, int[], int>
{
public override Puzzle PartOne => new()
{
Example = new()
{
Input = new[] { 1, 2, 3 },
Result = 3,
},
Solution = 5,
};
public override Puzzle PartTwo => new()
{
Example = new()
{
Input = new[] { 1, 2, 3 },
Result = 6,
},
Solution = 15,
};
}
That's pretty much all about it, I hope that it will help others to get through this year's puzzle, and see you on the 24th! 🎄
Photo by Michel Stockman on Unsplash
Top comments (0)