{"id":21763639,"url":"https://github.com/eduherminio/aochelper","last_synced_at":"2025-08-20T08:33:14.922Z","repository":{"id":36459998,"uuid":"217520517","full_name":"eduherminio/AoCHelper","owner":"eduherminio","description":"Helper .NET library for solving Advent of Code puzzles","archived":false,"fork":false,"pushed_at":"2024-04-12T10:53:29.000Z","size":198,"stargazers_count":55,"open_issues_count":7,"forks_count":8,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-04-12T17:24:04.077Z","etag":null,"topics":["advent","advent-of-code","advent-of-code-2021","advent-of-code-2022","advent-of-code-2023","adventofcode","adventofcode2021","adventofcode2022","adventofcode2023","aoc","aoc2021","aoc2022","aoc2023","puzzles"],"latest_commit_sha":null,"homepage":"https://adventofcode.com","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eduherminio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-10-25T11:37:25.000Z","updated_at":"2024-04-14T18:44:26.511Z","dependencies_parsed_at":"2023-01-17T01:40:03.333Z","dependency_job_id":"91d34733-f990-4ccb-80f3-11c59e2ef735","html_url":"https://github.com/eduherminio/AoCHelper","commit_stats":null,"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eduherminio%2FAoCHelper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eduherminio%2FAoCHelper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eduherminio%2FAoCHelper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eduherminio%2FAoCHelper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eduherminio","download_url":"https://codeload.github.com/eduherminio/AoCHelper/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230408171,"owners_count":18220974,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["advent","advent-of-code","advent-of-code-2021","advent-of-code-2022","advent-of-code-2023","adventofcode","adventofcode2021","adventofcode2022","adventofcode2023","aoc","aoc2021","aoc2022","aoc2023","puzzles"],"created_at":"2024-11-26T12:15:54.554Z","updated_at":"2024-12-19T09:07:53.158Z","avatar_url":"https://github.com/eduherminio.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AoCHelper\n\n[![GitHub Actions][githubactionslogo]][githubactionslink]\n[![Nuget][nugetlogo]][nugetlink]\n\n**AoCHelper** is a support library for solving [Advent of Code](https://adventofcode.com/) puzzles, available for .NET and .NET Standard 2.x.\n\nIt provides a 'framework' so that you only have to worry about solving the problems, and measures the performance of your solutions.\n\nProblem example:\n\n```csharp\nusing AoCHelper;\nusing System.Threading.Tasks;\n\nnamespace AdventOfCode;\n\npublic class Day_01 : BaseDay\n{\n    public override ValueTask\u003cstring\u003e Solve_1() =\u003e new(\"Solution 1\");\n\n    public override ValueTask\u003cstring\u003e Solve_2() =\u003e new(\"Solution 2\");\n}\n```\n\nOutput example:\n\n![aochelper](https://user-images.githubusercontent.com/11148519/142051856-16d9d5bf-885c-44cd-94ae-6f678bcbc04f.gif)\n\n## AdventOfCode.Template\n\nCreating your Advent of Code repository from [**AdventOfCode.Template**](https://github.com/eduherminio/AdventOfCode.Template) is the quickest way to get up and running with `AoCHelper`.\n\nThere's also [AdventOfCode.MultiYearTemplate](https://github.com/eduherminio/AdventOfCode.MultiYearTemplate) available of you want to keep all the years in the same repository, but I'd recommend to use the former one if you're participating in Advent of Code or using AoCHelper for the first time.\n\n## Simple usage\n\n- **Add [AoCHelper NuGet package](https://www.nuget.org/packages/AoCHelper/)** to your project.\n- **Create one class per day/problem**, using one of the following approaches:\n  - Name them `DayXX` or `Day_XX` and make them inherit `BaseDay`.\n  - Name them `ProblemXX` or `Problem_XX`and make them inherit `BaseProblem`.\n- **Put your input files under `Inputs/` directory** and follow `XX.txt` naming convention for day `XX`. Make sure to copy those files to your output folder.\n- Choose your **solving strategy** in your `Main()` method, adjusting it with your custom `Action\u003cSolverConfiguration\u003e` if needed:\n  - `Solver.SolveAll();`\n  - `Solver.SolveLast();`\n  - `Solver.SolveLast(opt =\u003e opt.ClearConsole = false);`\n  - `Solver.Solve\u003cDay_05\u003e();`\n  - `Solver.Solve(new List\u003cuint\u003e{ 5, 6 });`\n  - `Solver.Solve(new List\u003cType\u003e { typeof(Day_05), typeof(Day_06) });`\n\n## Customization\n\nA **custom `Action\u003cSolverConfiguration\u003e`** can be provided to any of the `Solver` methods. It has the following configurable options (`false` or `null` by default unless otherwise specified):\n\n- **`bool ClearConsole`**: Clears previous runs information from the console. True by default.\n- **`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.\n- **`bool ShowConstructorElapsedTime`**: Shows the time elapsed during the instantiation of a `BaseProblem`. This normally reflects the elapsed time while parsing the input data.\n- **`bool ShowTotalElapsedTimePerDay`**: Shows total elapsed time per day. This includes constructor time + part 1 + part 2.\n- **`string? ElapsedTimeFormatSpecifier`**: Custom numeric format strings used for elapsed milliseconds. See [Standard numeric format strings](https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings).\n- **`List\u003cAssembly\u003e`**: Assembly/Assemblies where the problems are located. Defaults to `Assembly.GetEntryAssembly()`, which assumes the problems are in the same project where `Solver` is invoked.\n\n## Advanced usage\n\nYou can also:\n\n- Create your own abstract base class tha(t inherits `BaseProblem`, make all your problem classes inherit it and use this custom base class to:\n  - Override `ClassPrefix` property, to be able to follow your own `$(ClassPrefix)XX` or `$(ClassPrefix)_XX` convention in each one of your problem classes.\n  - Override `InputFileDirPath` to change the input files directory\n  - Override `InputFileExtension` to change the input files extension.\n  - Override `CalculateIndex()` to follow a different `XX` or `_XX` convention in your class names.\n  - Override `InputFilePath` to follow a different naming convention in your input files. Check the [current implementation](https://github.com/eduherminio/AoCHelper/blob/master/src/AoCHelper/BaseProblem.cs) to understand how to reuse all the other properties and methods.\n- _[Not recommended]_ Override `InputFilePath` in any specific problem class to point to a concrete file. This will make the values of `ClassPrefix`, `InputFileDirPath` and `InputFileExtension` and the implementation of `CalculateIndex()` irrelevant (see the [current implementation](https://github.com/eduherminio/AoCHelper/blob/master/src/AoCHelper/BaseProblem.cs)).\n\n## Testing\n\n- Example of simple AoC solutions testing: [SampleTests](tests/AoCHelper.Test/SampleTests.cs)\n- Example of advanced AoC solutions testing by providing a custom input test filepath: [ModifyInputFilePathTests_SampleTests](tests/AoCHelper.Test/ModifyInputFilePathTests_SampleTests.cs)\n- Example of advanced AoC solutions testing by providing a custom input test dir path: [ModifyInputFileDirPath_SampleTests](tests/AoCHelper.Test/ModifyInputFileDirPath_SampleTests.cs)\n\n## Usage examples\n\nExample projects can be found at:\n\n- [AoC2023](https://github.com/eduherminio/AoC2023) (v3.x)\n- [AoC2022](https://github.com/eduherminio/AoC2022) (v2.x)\n- [AoC2021](https://github.com/eduherminio/AoC2021) (v1.x)\n- [AdventOfCode.Template](https://github.com/eduherminio/AdventOfCode.Template)\n- [AoCHelper.PoC](src/AoCHelper.PoC)\n- [AoCHelper.Test](tests/AoCHelper.Test)\n- [AoC2020](https://github.com/eduherminio/AoC2020) (v0.x)\n- [All these repositories](https://github.com/eduherminio/AoCHelper/network/dependents)\n\nSome cool repositories that add their own abstractions/customizations on top of `AocHelper`:\n\n- [RachaelBooth/AdventOfCode2022](https://github.com/RachaelBooth/AdventOfCode2022/): `BaseSolver\u003cU\u003e` and `BaseSolver\u003cU, V\u003e` wrappers around `BaseProblem` to have `U Solve1()` and `V Solve2` methods.\n- [Morphix84/AdventOfCode](https://github.com/Morphix84/AdventOfCode/): input fetching and same-repository-multi-year support.\n- [codemonkey85/Advent-of-Code-2023](https://github.com/codemonkey85/Advent-of-Code-2023): problems located in a library project and `Solver` invoked from both a CLI and a Web project.\n\n## `v1` to `v2+` migration\n\nMethods that accept an instance of `SolverConfiguration` were deprecated in `v2` and removed in `v3`.\n\nThey have been replaced by methods that accept `Action\u003cSolverConfiguration\u003e`.\n\n`v1`:\n\n```csharp\nawait Solver.SolveAll(new SolverConfiguration\n{\n    ShowConstructorElapsedTime = true,\n    ShowOverallResults = true,\n    ClearConsole = false\n});\n```\n\n`v2+`:\n\n```csharp\nawait Solver.SolveAll(options =\u003e\n{\n    options.ShowConstructorElapsedTime = true;\n    options.ShowOverallResults = true;\n    options.ClearConsole = false;\n});\n```\n\n## `v0.x` to `v1.x` migration\n\n`BaseProblem.Solve_1()` and `BaseProblem.Solve_2()` signature has changed: they must return `ValueTask\u003cstring\u003e` now.\n\n`ValueTask\u003cT\u003e` has constructors that accept both `T` and `Task\u003cT\u003e`, so:\n\n`v0.x`:\n\n```csharp\npublic class Day_01 : BaseDay\n{\n    public override string Solve_1() =\u003e \"Solution 2\";\n\n    public override string Solve_2() =\u003e FooAsync().Result;\n\n    private async Task\u003cstring\u003e FooAsync()\n    {\n        await Task.Delay(1000);\n        return \"Solution 2\";\n    }\n}\n```\n\nbecomes now in `v1.x`:\n\n```csharp\npublic class Day_01 : BaseDay\n{\n    public override ValueTask\u003cstring\u003e Solve_1() =\u003e new(\"Solution 2\");\n\n    public override ValueTask\u003cstring\u003e Solve_2() =\u003e new(FooAsync());\n\n    private async Task\u003cstring\u003e FooAsync()\n    {\n        await Task.Delay(1000);\n        return \"Solution 2\";\n    }\n}\n```\n\nor in case we prefer `async`/`await` over returning the task, as recommended [here](https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md#prefer-asyncawait-over-directly-returning-task):\n\n```csharp\npublic class Day_01 : BaseDay\n{\n    public override ValueTask\u003cstring\u003e Solve_1() =\u003e new(\"Solution 2\");\n\n    public override async ValueTask\u003cstring\u003e Solve_2() =\u003e new(await FooAsync());\n\n    private async Task\u003cstring\u003e FooAsync()\n    {\n        await Task.Delay(1000);\n        return \"Solution 2\";\n    }\n}\n```\n\n## Tips\n\nYour problem/day classes are instantiated only once, so parsing the input file (`InputFilePath`) in your class constructor allows you to:\n\n- Avoid executing parsing logic twice per problem.\n- Measure more accurately your part 1 and part 2 solutions performance\\*.\n\n\\* Consider enabling `ShowConstructorElapsedTime` and `ShowTotalElapsedTimePerDay` in `Action\u003cSolverConfiguration\u003e`.\n\n[githubactionslogo]: https://github.com/eduherminio/AoCHelper/workflows/CI/badge.svg\n[githubactionslink]: https://github.com/eduherminio/AoCHelper/actions?query=workflow%3ACI\n[nugetlogo]: https://img.shields.io/nuget/v/AocHelper.svg?style=flat-square\u0026label=nuget\n[nugetlink]: https://www.nuget.org/packages/AocHelper\n\n## Other libraries templates and projects\n\nFeel free to experiment with this project and the related templates I provide to create your own thing. There are a few examples under [Usage examples](#usage-examples) that show how to create your custom framework on top of `AoCHelper`.\n\nIf there's something in this project that just doesn't click for you, there are dozens of alternatives out there that you can explore instead. These are some well-known examples:\n\n- [viceroypenguin/adventofcode.template](https://github.com/viceroypenguin/adventofcode.template): supports more accurate benchmarks using `BenchmarkDotNet`.\n- [Zaneris/AdventOfCodeSupport](https://github.com/Zaneris/AdventOfCodeSupport): supports automatic input downloading and solution submitting.\n\nI would also like to encourage anyone to create their own libraries or templates. Nothing like building your own!\n\nBut beware, you might spend more time working on the template than on the problems themselves (been there, done that, would do it again!).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feduherminio%2Faochelper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feduherminio%2Faochelper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feduherminio%2Faochelper/lists"}