Skip to content

Commit a50a98e

Browse files
committed
Create a strategy to handle the local inputs
1 parent b9524b0 commit a50a98e

File tree

9 files changed

+64
-34
lines changed

9 files changed

+64
-34
lines changed

src/AdventOfCode.Commons/AdventOfCode.Commons.csproj

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFramework>net7.0</TargetFramework>
@@ -8,6 +8,14 @@
88
<IsPackable>false</IsPackable>
99
</PropertyGroup>
1010

11+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
12+
<LangVersion>preview</LangVersion>
13+
</PropertyGroup>
14+
15+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
16+
<LangVersion>preview</LangVersion>
17+
</PropertyGroup>
18+
1119
<ItemGroup>
1220
<PackageReference Include="FluentAssertions" Version="6.8.0" />
1321
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace AdventOfCode.Commons.Input;
2+
3+
public interface IPuzzleInputReaderStrategy
4+
{
5+
IEnumerable<string> ReadInput();
6+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace AdventOfCode.Commons.Input;
2+
3+
public class LocalPuzzleInputReaderStrategy : IPuzzleInputReaderStrategy
4+
{
5+
public required string InputPath { get; init; }
6+
7+
public IEnumerable<string> ReadInput()
8+
=> File.ReadAllLines(InputPath);
9+
}

src/AdventOfCode.Commons/Solver.cs

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace AdventOfCode.Commons;
1+
using AdventOfCode.Commons.Input;
2+
3+
namespace AdventOfCode.Commons;
24

35
/// <summary>
46
/// Represent the solver used for a given day
@@ -13,31 +15,41 @@
1315
/// </typeparam>
1416
public abstract class Solver<TInput, TResult>
1517
{
16-
/// <summary>
17-
/// The path to the input file (ex: <c>"day1/input.txt"</c>)
18-
/// </summary>
19-
protected abstract string InputPath { get; }
18+
public readonly Lazy<TInput> Input;
19+
20+
private Solver(IPuzzleInputReaderStrategy puzzleInputReader)
21+
{
22+
Input = new Lazy<TInput>(() =>
23+
{
24+
var content = puzzleInputReader.ReadInput();
25+
return ParseInput(content);
26+
});
27+
}
2028

21-
public readonly TInput Input;
29+
protected Solver(string inputPath)
30+
: this(new LocalPuzzleInputReaderStrategy { InputPath = inputPath }) { }
31+
32+
protected Solver(int year, int day)
33+
: this(new RemotePuzzleInputReaderStrategy { Year = year, Day = day }) { }
2234

23-
protected Solver()
24-
=> Input = ReadInput(InputPath);
2535

2636
/// <summary>
27-
/// Logic for the solution of the first part of the puzzle
37+
/// Parse the input file and convert it to <typeparamref name="TInput"/>
38+
/// for it to be used as the input of the <see cref="PartOne(TInput)"/>
39+
/// and <see cref="PartTwo(TInput)"/>
2840
/// </summary>
2941
///
30-
/// <param name="input">
31-
/// The digested puzzle input
42+
/// <param name="inputPath">
43+
/// The path of your puzzle input
3244
/// </param>
3345
///
3446
/// <returns>
35-
/// The puzzle's solution
47+
/// The digested input
3648
/// </returns>
37-
public abstract TResult PartOne(TInput input);
49+
public abstract TInput ParseInput(IEnumerable<string> input);
3850

3951
/// <summary>
40-
/// Logic for the solution of the second part of the puzzle
52+
/// Logic for the solution of the first part of the puzzle
4153
/// </summary>
4254
///
4355
/// <param name="input">
@@ -47,20 +59,18 @@ protected Solver()
4759
/// <returns>
4860
/// The puzzle's solution
4961
/// </returns>
50-
public abstract TResult PartTwo(TInput input);
62+
public abstract TResult PartOne(TInput input);
5163

5264
/// <summary>
53-
/// Parse the input file and convert it to <typeparamref name="TInput"/>
54-
/// for it to be used as the input of the <see cref="PartOne(TInput)"/>
55-
/// and <see cref="PartTwo(TInput)"/>
65+
/// Logic for the solution of the second part of the puzzle
5666
/// </summary>
5767
///
58-
/// <param name="inputPath">
59-
/// The path of your puzzle input
68+
/// <param name="input">
69+
/// The digested puzzle input
6070
/// </param>
6171
///
6272
/// <returns>
63-
/// The digested input
73+
/// The puzzle's solution
6474
/// </returns>
65-
public abstract TInput ReadInput(string inputPath);
75+
public abstract TResult PartTwo(TInput input);
6676
}

src/AdventOfCode.Commons/TestEngine.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public void PartOneSolutionTest()
8585
{
8686
var input = _solver.Input;
8787

88-
var result = _solver.PartOne(input);
88+
var result = _solver.PartOne(input.Value);
8989

9090
result.Should().Be(PartOne.Solution);
9191
}
@@ -111,7 +111,7 @@ public void PartTwoSolutionTest()
111111
{
112112
var input = _solver.Input;
113113

114-
var result = _solver.PartTwo(input);
114+
var result = _solver.PartTwo(input.Value);
115115

116116
result.Should().Be(PartTwo.Solution);
117117
}

src/AdventOfCode.Usage/AdventOfCode.Usage.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
</ItemGroup>
2727

2828
<ItemGroup>
29-
<None Update="input.txt">
29+
<None Update="WithLocalInput\input.txt">
3030
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
3131
</None>
3232
</ItemGroup>
Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using AdventOfCode.Commons;
22

3-
namespace AdventOfCode.Usage;
3+
namespace AdventOfCode.Usage.WithLocalInput;
44

55
/// <summary>
66
/// Example of how to use the <see cref="Solver{TInput, TResult}"/> for a simple puzzle
@@ -13,17 +13,14 @@ namespace AdventOfCode.Usage;
1313
/// </summary>
1414
public class Solver : Solver<int[], int>
1515
{
16-
protected override string InputPath => "input.txt";
16+
public Solver() : base(inputPath: "WithLocalInput/input.txt") { }
1717

1818
public override int PartOne(int[] input)
1919
=> input.Max();
2020

2121
public override int PartTwo(int[] input)
2222
=> input.Sum();
2323

24-
public override int[] ReadInput(string inputPath)
25-
=> File
26-
.ReadAllLines(inputPath)
27-
.Select(int.Parse)
28-
.ToArray();
24+
public override int[] ParseInput(IEnumerable<string> input)
25+
=> input.Select(int.Parse).ToArray();
2926
}

src/AdventOfCode.Usage/SolverTest.cs renamed to src/AdventOfCode.Usage/WithLocalInput/SolverTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using AdventOfCode.Commons;
22

3-
namespace AdventOfCode.Usage;
3+
namespace AdventOfCode.Usage.WithLocalInput;
44

55
/// <summary>
66
/// Example of how to test the <see cref="Solver{TInput, TResult}"/>
File renamed without changes.

0 commit comments

Comments
 (0)