This repo contains solutions to a variety of code challenges.
bash:
./run.sh <challenge selector>powershell / cmd.exe:
./run <challenge selector>Run the above commands without any arguments to see the support challenges. The first segment of the challenge selector is case-insensitive.
- Install the project template
dotnet new install ./Templates/CodeChallenge.Template.Solution/
- The template can be reinstalled to pick up changes by running
dotnet new install --force ./Templates/CodeChallenge.Template.Solution/
- The template can be reinstalled to pick up changes by running
- Create the template
# From inside the target C# project folder (such as ./Solutions/AdventOfCode/AdventOfCode2021/) dotnet new codechallenge.solution --ShortName <Project Shortname> # From inside the Solution Folder (such as ./Solutions/AdventOfCode/) dotnet new codechallenge.solution -n <Full Project Name> --ShortName <Project Shortname> # From anywhere dotnet new codechallenge.solution -n <Full Project Name> --ShortName <Project Shortname> -o <Path to C# project folder>
- The project short name is used to name the classes in the template
- For example, if
--ShortName DemoChallengewas passed, one class name might beAbstractDemoChallengeSolution
- For example, if
- The project short name is used to name the classes in the template
- Add the project to the solution
- Implement the top-level types as needed
- For fetching and parsing input, it is recommended to use
IInputProviderBuilder<TChallengeSelection>
- For fetching and parsing input, it is recommended to use
- Create the project at the path
Solutions/<Challenge Name>/<Project Folder>/<Project>.csproj - Extend
ChallengeSelectionas a way to indicate a particular problem & solution within the challenge space. - Extend
IInputFilePathProvider<TChallengeSelection>as needed- This type is used for getting the path to input files (i.e.
Resources/<Challenge>/...) - This is only needed if the new solutions will rely on the default
InputReaderbehavior:InputReaderreads the entire file, splits on\n, and trims each line. It also discards any lines which are empty.- The returned value is
IEnumerable<string>
- If input must be read in a way that differs from
InputReader, an implementation ofIInputFilePathProvider<>is not mandatory. - Input files should be places in
Resources/<Challenge Name>/with the folder structure within left up to the solution to organize as it makes sense - Register any implementations of
IInputFilePathProvider<TChallengeSelection>in Autofac- The abstract Autofac module
InputFilePathProviderAutoRegisteringModulecan be extended to automatically register implementations in the challenge space's assembly automatically.
- The abstract Autofac module
- This type is used for getting the path to input files (i.e.
- Optionally extend
IInputProvider<TChallengeSelection, TOutput>as needed- This step should only be considered if the input requires a lot of custom parsing logic and can be applied across all solutions in the project.
- The recommended approach is to use
IInputProviderBuilder<TChallengeSelection>
- The recommended approach is to use
- This type is used for getting input (typically via an instance of
IInputProvider<TChallengeSelection>, but not always) and modifying it to prepare it for the individual solution implementations. This can be as simple as parsing each line as anint, but anything can be returned. - Register any implementations of
IInputProvider<TChallengeSelection, TOutput>in Autofac- The abstract Autofac module
InputProviderAutoRegisteringModulecan be extended to automatically register implementations in the challenge space's assembly automatically.
- The abstract Autofac module
- This step should only be considered if the input requires a lot of custom parsing logic and can be applied across all solutions in the project.
- Implement a
System.CommandLine.Commandfor executing the new solution type.AbstractCodeChallengeCommand<T>can be extended to inherit theExecuteSolutionAsyncmethod for use as the command's handler- Dependencies can be taken as
IValueDescriptor<T>and passed toSetHandler()AutofacBinder<T>is registered in Autofac for allIValueDescriptor<T>, so that dependencies can be resolved in Commands at runtime
- Extend
SolutionAttributefor flagging the solution classes- Take any indicators (such as year, day, and puzzle in the case of Advent of Code) via the constructor and set them in public properties.
- The implementation of the abstract method
ToPuzzleSelection()should return an instance of the type created in step 4.
- It is recommended to create an abstract
Solutionbase class for all solutions within a challenge space.- At a minimum, each solution must implement
ISolution, but if each problem must be executed in a different way, then the abstract base is not needed. - There is an
AbstractSolution<TSolutionAttribute, TChallengeSelection>which can be extended to provide some helper methods in the solution implementation.- In particular, it provides a method for getting the current
ChallengeSelectionvia reflection of theSolutionAttribute. - This is most useful when creating another abstract base Solution type for an entire challenge space. Stand-alone Solution implementations may not need this functionality.
- In particular, it provides a method for getting the current
- At a minimum, each solution must implement
- Create Solution implementations
- There are only two requirements here:
- Must implement
ISolution - Must annotate the class with an attribute derived from
SolutionAttribute
- Must implement
- There are only two requirements here:
- Register Solutions in Autofac
- The abstract Autofac module
SolutionAutoRegisteringModulecan be extended to automatically register implementations in the challenge space's assembly automatically.
- The abstract Autofac module
- Add input files to
Resources/<Challenge Name>/, with the nested folder structure left up to the solution to organize as it makes sense.