Added support for multiple data root paths
This commit is contained in:
parent
824ec0e29b
commit
801f8aa643
|
@ -54,7 +54,10 @@ var
|
||||||
n: Integer;
|
n: Integer;
|
||||||
begin
|
begin
|
||||||
WriteLn('### Advent of Code 2023 ###');
|
WriteLn('### Advent of Code 2023 ###');
|
||||||
engine := TSolverEngine.Create('data');
|
engine := TSolverEngine.Create(TStringArray.Create(
|
||||||
|
'data',
|
||||||
|
ConcatPaths(['..', '..', 'data'])
|
||||||
|
));
|
||||||
|
|
||||||
solvers := specialize TList<Integer>.Create;
|
solvers := specialize TList<Integer>.Create;
|
||||||
if HasOption('p', 'puzzle') then
|
if HasOption('p', 'puzzle') then
|
||||||
|
|
66
USolver.pas
66
USolver.pas
|
@ -63,13 +63,15 @@ type
|
||||||
|
|
||||||
TSolverEngine = class
|
TSolverEngine = class
|
||||||
private
|
private
|
||||||
FRelativeDataPath: string;
|
FRelativeDataPaths: TStringArray;
|
||||||
public
|
public
|
||||||
constructor Create(const ARelativeDataPath: string);
|
constructor Create(constref ARelativeDataPaths: TStringArray);
|
||||||
procedure ProcessData(const ASolver: ISolver);
|
procedure ProcessData(const ASolver: ISolver);
|
||||||
procedure Run(const ASolver: ISolver);
|
procedure Run(const ASolver: ISolver);
|
||||||
procedure RunAndFree(const ASolver: ISolver);
|
procedure RunAndFree(const ASolver: ISolver);
|
||||||
function GetDataFileName(const ASolver: ISolver): string;
|
function HasValidDataPath(const ASolver: ISolver): Boolean;
|
||||||
|
function TryGetFirstValidDataPath(const ASolver: ISolver; out ODataFilePath: string): Boolean;
|
||||||
|
function GetInvalidDataPathMessage(const ASolver: ISolver): string;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
@ -94,19 +96,22 @@ end;
|
||||||
|
|
||||||
{ TSolverEngine }
|
{ TSolverEngine }
|
||||||
|
|
||||||
constructor TSolverEngine.Create(const ARelativeDataPath: string);
|
constructor TSolverEngine.Create(constref ARelativeDataPaths: TStringArray);
|
||||||
begin
|
begin
|
||||||
FRelativeDataPath := ARelativeDataPath;
|
if (ARelativeDataPaths = nil) or (Length(ARelativeDataPaths) = 0) then
|
||||||
|
raise EArgumentOutOfRangeException.Create('Must specify at least one data path.');
|
||||||
|
FRelativeDataPaths := ARelativeDataPaths;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSolverEngine.ProcessData(const ASolver: ISolver);
|
procedure TSolverEngine.ProcessData(const ASolver: ISolver);
|
||||||
var
|
var
|
||||||
data: TextFile;
|
data: TextFile;
|
||||||
s: string;
|
dataFilePath, s: string;
|
||||||
begin
|
begin
|
||||||
ASolver.Init;
|
ASolver.Init;
|
||||||
|
|
||||||
AssignFile(data, GetDataFileName(ASolver));
|
TryGetFirstValidDataPath(ASolver, dataFilePath);
|
||||||
|
AssignFile(data, dataFilePath);
|
||||||
try
|
try
|
||||||
reset(data);
|
reset(data);
|
||||||
while (not EOF(data)) do
|
while (not EOF(data)) do
|
||||||
|
@ -122,22 +127,17 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSolverEngine.Run(const ASolver: ISolver);
|
procedure TSolverEngine.Run(const ASolver: ISolver);
|
||||||
var
|
|
||||||
fileName: string;
|
|
||||||
begin
|
begin
|
||||||
WriteLn;
|
WriteLn;
|
||||||
WriteLn('--- ', ASolver.PuzzleName, ' ---');
|
WriteLn('--- ', ASolver.PuzzleName, ' ---');
|
||||||
fileName := GetDataFileName(ASolver);
|
if HasValidDataPath(ASolver) then
|
||||||
if FileExists(fileName) then
|
|
||||||
begin
|
begin
|
||||||
ProcessData(ASolver);
|
ProcessData(ASolver);
|
||||||
WriteLn('Part 1: ', ASolver.ResultPart1);
|
WriteLn('Part 1: ', ASolver.ResultPart1);
|
||||||
WriteLn('Part 2: ', ASolver.ResultPart2);
|
WriteLn('Part 2: ', ASolver.ResultPart2);
|
||||||
end
|
end
|
||||||
else begin
|
else
|
||||||
WriteLn('Cannot find puzzle input file ''', ExpandFileName(fileName), '''.');
|
WriteLn(GetInvalidDataPathMessage(ASolver));
|
||||||
WriteLn('Please download the file content from https://adventofcode.com/2023/');
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSolverEngine.RunAndFree(const ASolver: ISolver);
|
procedure TSolverEngine.RunAndFree(const ASolver: ISolver);
|
||||||
|
@ -146,9 +146,41 @@ begin
|
||||||
ASolver.Free;
|
ASolver.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSolverEngine.GetDataFileName(const ASolver: ISolver): string;
|
function TSolverEngine.HasValidDataPath(const ASolver: ISolver): Boolean;
|
||||||
|
var
|
||||||
|
s: string;
|
||||||
begin
|
begin
|
||||||
Result := ConcatPaths([FRelativeDataPath, ASolver.DataFileName]);
|
Result := TryGetFirstValidDataPath(ASolver, s);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSolverEngine.TryGetFirstValidDataPath(const ASolver: ISolver; out ODataFilePath: string): Boolean;
|
||||||
|
var
|
||||||
|
path: string;
|
||||||
|
begin
|
||||||
|
for path in FRelativeDataPaths do
|
||||||
|
begin
|
||||||
|
ODataFilePath := ConcatPaths([path, ASolver.DataFileName]);
|
||||||
|
if FileExists(ODataFilePath) then
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result := False;
|
||||||
|
ODataFilePath := '';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSolverEngine.GetInvalidDataPathMessage(const ASolver: ISolver): string;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
Result := 'Cannot find puzzle input file '''
|
||||||
|
+ ExpandFileName(ConcatPaths([FRelativeDataPaths[0], ASolver.DataFileName]));
|
||||||
|
for i := 1 to Length(FRelativeDataPaths) - 1 do
|
||||||
|
Result := Result + ''', or '''
|
||||||
|
+ ExpandFileName(ConcatPaths([FRelativeDataPaths[i], ASolver.DataFileName]));
|
||||||
|
Result := Result + '''. Please download the file content from https://adventofcode.com/2023/';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
|
@ -43,14 +43,14 @@ type
|
||||||
FEngine: TSolverEngine;
|
FEngine: TSolverEngine;
|
||||||
procedure Setup; override;
|
procedure Setup; override;
|
||||||
procedure TearDown; override;
|
procedure TearDown; override;
|
||||||
function GetDataPath: string; virtual;
|
function GetDataPaths: TStringArray; virtual;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TExampleEngineBaseTest }
|
{ TExampleEngineBaseTest }
|
||||||
|
|
||||||
TExampleEngineBaseTest = class(TEngineBaseTest)
|
TExampleEngineBaseTest = class(TEngineBaseTest)
|
||||||
protected
|
protected
|
||||||
function GetDataPath: string; override;
|
function GetDataPaths: TStringArray; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
@ -72,15 +72,10 @@ end;
|
||||||
{ TEngineBaseTest }
|
{ TEngineBaseTest }
|
||||||
|
|
||||||
procedure TEngineBaseTest.Setup;
|
procedure TEngineBaseTest.Setup;
|
||||||
var
|
|
||||||
fileName: string;
|
|
||||||
begin
|
begin
|
||||||
inherited Setup;
|
inherited Setup;
|
||||||
FEngine := TSolverEngine.Create(GetDataPath);
|
FEngine := TSolverEngine.Create(GetDataPaths);
|
||||||
fileName := FEngine.GetDataFileName(FSolver);
|
AssertTrue(FEngine.GetInvalidDataPathMessage(FSolver), FEngine.HasValidDataPath(FSolver));
|
||||||
AssertTrue('Cannot find puzzle input file ''' + ExpandFileName(fileName) + '''. '
|
|
||||||
+ 'Please download the file from https://adventofcode.com/2023/',
|
|
||||||
FileExists(fileName));
|
|
||||||
FEngine.ProcessData(FSolver);
|
FEngine.ProcessData(FSolver);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -90,16 +85,22 @@ begin
|
||||||
inherited TearDown;
|
inherited TearDown;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TEngineBaseTest.GetDataPath: string;
|
function TEngineBaseTest.GetDataPaths: TStringArray;
|
||||||
begin
|
begin
|
||||||
Result := ConcatPaths(['..', '..', 'bin', 'data']);
|
Result := TStringArray.Create(
|
||||||
|
ConcatPaths(['..', '..', 'bin', 'data']),
|
||||||
|
ConcatPaths(['..', '..', '..', 'data'])
|
||||||
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TExampleEngineBaseTest }
|
{ TExampleEngineBaseTest }
|
||||||
|
|
||||||
function TExampleEngineBaseTest.GetDataPath: string;
|
function TExampleEngineBaseTest.GetDataPaths: TStringArray;
|
||||||
begin
|
begin
|
||||||
Result := 'example_data';
|
Result := TStringArray.Create(
|
||||||
|
ConcatPaths(['..', '..', 'bin', 'data', 'example']),
|
||||||
|
ConcatPaths(['..', '..', '..', 'data', 'example'])
|
||||||
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
Loading…
Reference in New Issue