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