AoCHelper 3.1.0-alpha.1
See the version list below for details.
dotnet add package AoCHelper --version 3.1.0-alpha.1
NuGet\Install-Package AoCHelper -Version 3.1.0-alpha.1
<PackageReference Include="AoCHelper" Version="3.1.0-alpha.1" />
paket add AoCHelper --version 3.1.0-alpha.1
#r "nuget: AoCHelper, 3.1.0-alpha.1"
// Install AoCHelper as a Cake Addin #addin nuget:?package=AoCHelper&version=3.1.0-alpha.1&prerelease // Install AoCHelper as a Cake Tool #tool nuget:?package=AoCHelper&version=3.1.0-alpha.1&prerelease
AoCHelper
AoCHelper is a support library for solving Advent of Code puzzles, available for .NET and .NET Standard 2.x.
It provides a 'framework' so that you only have to worry about solving the problems, and measures the performance of your solutions.
Problem example:
using AoCHelper;
using System.Threading.Tasks;
namespace AdventOfCode;
public class Day_01 : BaseDay
{
public override ValueTask<string> Solve_1() => new("Solution 1");
public override ValueTask<string> Solve_2() => new("Solution 2");
}
Output example:
AdventOfCode.Template
Creating your Advent of Code repository from AdventOfCode.Template is the quickest way to get up and running with AoCHelper
.
Simple usage
- Add AoCHelper NuGet package to your project.
- Create one class per day/problem, using one of the following approaches:
- Name them
DayXX
orDay_XX
and make them inheritBaseDay
. - Name them
ProblemXX
orProblem_XX
and make them inheritBaseProblem
.
- Name them
- Put your input files under
Inputs/
directory and followXX.txt
naming convention for dayXX
. Make sure to copy those files to your output folder. - Choose your solving strategy in your
Main()
method, adjusting it with your customAction<SolverConfiguration>
if needed:Solver.SolveAll();
Solver.SolveLast();
Solver.SolveLast(opt => opt.ClearConsole = false);
Solver.Solve<Day_05>();
Solver.Solve(new List<uint>{ 5, 6 });
Solver.Solve(new List<Type> { typeof(Day_05), typeof(Day_06) });
Customization
A custom Action<SolverConfiguration>
can be provided to any of the Solver
methods. It has the following configurable options (false
or null
by default unless otherwise specified):
bool ClearConsole
: Clears previous runs information from the console. True by default.bool ShowOverallResults
: Shows a panel at the end of the run with aggregated stats of the solved problems. True by default when solving multiple problems, false otherwise.bool ShowConstructorElapsedTime
: Shows the time elapsed during the instantiation of aBaseProblem
. This normally reflects the elapsed time while parsing the input data.bool ShowTotalElapsedTimePerDay
: Shows total elapsed time per day. This includes constructor time + part 1 + part 2.string? ElapsedTimeFormatSpecifier
: Custom numeric format strings used for elapsed milliseconds. See Standard numeric format strings.
Advanced usage
You can also:
- Create your own abstract base class tha(t inherits
BaseProblem
, make all your problem classes inherit it and use this custom base class to:- Override
ClassPrefix
property, to be able to follow your own$(ClassPrefix)XX
or$(ClassPrefix)_XX
convention in each one of your problem classes. - Override
InputFileDirPath
to change the input files directory - Override
InputFileExtension
to change the input files extension. - Override
CalculateIndex()
to follow a differentXX
or_XX
convention in your class names. - Override
InputFilePath
to follow a different naming convention in your input files. Check the current implementation to understand how to reuse all the other properties and methods.
- Override
- [Not recommended] Override
InputFilePath
in any specific problem class to point to a concrete file. This will make the values ofClassPrefix
,InputFileDirPath
andInputFileExtension
and the implementation ofCalculateIndex()
irrelevant (see the current implementation).
Testing
- Example of simple AoC solutions testing: SampleTests
- Example of advanced AoC solutions testing by providing a custom input test filepath: ModifyInputFilePathTests_SampleTests
- Example of advanced AoC solutions testing by providing a custom input test dir path: ModifyInputFileDirPath_SampleTests
Usage examples
Example projects can be found at:
- AoC2023 (v3.x)
- AoC2022 (v2.x)
- AoC2021 (v1.x)
- AdventOfCode.Template
- AoCHelper.PoC
- AoCHelper.Test
- AoC2020 (v0.x)
- All these repositories
Some cool repositories that add their own abstractions/customizations on top of AocHelper
:
- RachaelBooth/AdventOfCode2022:
BaseSolver<U>
andBaseSolver<U, V>
wrappers aroundBaseProblem
to haveU Solve1()
andV Solve2
methods. - Morphix84/AdventOfCode: input fetching and same-repository-multi-year support.
v1
to v2+
migration
Methods that accept an instance of SolverConfiguration
were deprecated in v2
and removed in v3
.
They have been replaced by methods that accept Action<SolverConfiguration>
.
v1
:
await Solver.SolveAll(new SolverConfiguration
{
ShowConstructorElapsedTime = true,
ShowOverallResults = true,
ClearConsole = false
});
v2+
:
await Solver.SolveAll(options =>
{
options.ShowConstructorElapsedTime = true;
options.ShowOverallResults = true;
options.ClearConsole = false;
});
v0.x
to v1.x
migration
BaseProblem.Solve_1()
and BaseProblem.Solve_2()
signature has changed: they must return ValueTask<string>
now.
ValueTask<T>
has constructors that accept both T
and Task<T>
, so:
v0.x
:
public class Day_01 : BaseDay
{
public override string Solve_1() => "Solution 2";
public override string Solve_2() => FooAsync().Result;
private async Task<string> FooAsync()
{
await Task.Delay(1000);
return "Solution 2";
}
}
becomes now in v1.x
:
public class Day_01 : BaseDay
{
public override ValueTask<string> Solve_1() => new("Solution 2");
public override ValueTask<string> Solve_2() => new(FooAsync());
private async Task<string> FooAsync()
{
await Task.Delay(1000);
return "Solution 2";
}
}
or in case we prefer async
/await
over returning the task, as recommended here:
public class Day_01 : BaseDay
{
public override ValueTask<string> Solve_1() => new("Solution 2");
public override async ValueTask<string> Solve_2() => new(await FooAsync());
private async Task<string> FooAsync()
{
await Task.Delay(1000);
return "Solution 2";
}
}
Tips
Your problem/day classes are instantiated only once, so parsing the input file (InputFilePath
) in your class constructor allows you to:
- Avoid executing parsing logic twice per problem.
- Measure more accurately your part 1 and part 2 solutions performance*.
* Consider enabling ShowConstructorElapsedTime
and ShowTotalElapsedTimePerDay
in Action<SolverConfiguration>
.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Spectre.Console (>= 0.48.0)
- System.Threading.Tasks.Extensions (>= 4.5.4)
-
.NETStandard 2.1
- Spectre.Console (>= 0.48.0)
-
net6.0
- Spectre.Console (>= 0.48.0)
-
net7.0
- Spectre.Console (>= 0.48.0)
-
net8.0
- Spectre.Console (>= 0.48.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
4.0.0 | 516 | 11/24/2024 |
3.1.0 | 10,401 | 11/30/2023 |
3.1.0-alpha.1 | 83 | 11/28/2023 |
3.0.0 | 2,506 | 11/24/2023 |
3.0.0-alpha.1 | 76 | 11/20/2023 |
2.0.2 | 1,697 | 12/14/2022 |
2.0.2-alpha.1 | 128 | 12/11/2022 |
2.0.1 | 706 | 12/7/2022 |
2.0.0 | 1,416 | 11/12/2022 |
2.0.0-alpha.1 | 125 | 11/2/2022 |
1.0.2 | 1,873 | 11/29/2021 |
1.0.1 | 359 | 11/17/2021 |
1.0.0 | 355 | 11/16/2021 |
0.15.1 | 516 | 5/2/2021 |
0.15.0 | 796 | 12/16/2020 |
0.14.0 | 897 | 12/6/2020 |
0.13.0 | 467 | 12/4/2020 |
0.12.1 | 490 | 12/3/2020 |
0.11.0 | 511 | 12/2/2020 |
0.10.0 | 556 | 11/29/2020 |
0.9.0 | 453 | 11/29/2020 |
0.8.2 | 395 | 11/28/2020 |
0.8.1 | 410 | 11/28/2020 |
0.8.0 | 436 | 11/28/2020 |
0.7.0 | 403 | 11/26/2020 |
0.7.0-alpha.1 | 236 | 11/25/2020 |
0.6.0 | 421 | 11/24/2020 |
0.5.1 | 420 | 11/12/2020 |
0.5.0 | 493 | 5/3/2020 |
0.5.0-alpha-1 | 359 | 5/3/2020 |
0.4.0 | 506 | 2/29/2020 |
0.3.1 | 511 | 12/6/2019 |
0.3.0 | 506 | 12/6/2019 |
0.2.3 | 510 | 12/3/2019 |
0.2.2 | 524 | 12/3/2019 |
0.2.1 | 510 | 12/3/2019 |
0.2.0 | 494 | 12/2/2019 |
0.1.0 | 486 | 12/2/2019 |
0.1.0-alpha | 396 | 11/29/2019 |