Added solution for "Day 5: If You Give A Seed A Fertilizer", part 1
This commit is contained in:
parent
931b4b60f9
commit
c9e9eca35a
|
@ -49,6 +49,10 @@
|
|||
<Filename Value="solvers\UScratchcards.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="UGiveSeedFertilizer.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -25,7 +25,7 @@ uses
|
|||
{$ENDIF}
|
||||
Classes, SysUtils, CustApp,
|
||||
USolver,
|
||||
UTrebuchet, UCubeConundrum, UGearRatios, UScratchcards;
|
||||
UTrebuchet, UCubeConundrum, UGearRatios, UScratchcards, UGiveSeedFertilizer;
|
||||
|
||||
type
|
||||
|
||||
|
@ -54,6 +54,7 @@ begin
|
|||
engine := TSolverEngine.Create('data');
|
||||
engine.RunAndFree(TGearRatios.Create);
|
||||
engine.RunAndFree(TScratchcards.Create);
|
||||
engine.RunAndFree(TGiveSeedFertilizer.Create);
|
||||
engine.Free;
|
||||
end;
|
||||
|
||||
|
|
|
@ -0,0 +1,208 @@
|
|||
{
|
||||
Solutions to the Advent Of Code.
|
||||
Copyright (C) 2023 Stefan Müller
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
}
|
||||
|
||||
unit UGiveSeedFertilizer;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, fgl, USolver;
|
||||
|
||||
type
|
||||
|
||||
{ TAlmanacMapRange }
|
||||
|
||||
TAlmanacMapRange = class
|
||||
private
|
||||
FDestinationStart, FSourceStart, FSourceEnd, FDifference1, FDifference2: Cardinal;
|
||||
public
|
||||
constructor Create(const ADestinationStart, ASourceStart, ALength: Cardinal);
|
||||
function TryConvert(const AInput: Cardinal; out OOutput: Cardinal): Boolean;
|
||||
end;
|
||||
|
||||
{ TAlmanacMap }
|
||||
|
||||
TAlmanacMap = class
|
||||
private
|
||||
FRanges: specialize TFPGObjectList<TAlmanacMapRange>;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure AddMapRange(const ALine: string);
|
||||
function Convert(const AInput: Cardinal): Cardinal;
|
||||
end;
|
||||
|
||||
{ TGiveSeedFertilizer }
|
||||
|
||||
TGiveSeedFertilizer = class(TSolver)
|
||||
private
|
||||
FSeeds: specialize TFPGList<Cardinal>;
|
||||
FMaps: specialize TFPGObjectList<TAlmanacMap>;
|
||||
procedure ProcessSeeds(const ALine: string);
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure ProcessDataLine(const ALine: string); override;
|
||||
procedure Finish; override;
|
||||
function GetDataFileName: string; override;
|
||||
function GetPuzzleName: string; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TAlmanacMapRange }
|
||||
|
||||
constructor TAlmanacMapRange.Create(const ADestinationStart, ASourceStart, ALength: Cardinal);
|
||||
begin
|
||||
FDestinationStart := ADestinationStart;
|
||||
FSourceStart := ASourceStart;
|
||||
|
||||
// All input values are within Cardinal range, but the calculations might not be.
|
||||
if ASourceStart <= Cardinal.MaxValue - ALength then
|
||||
FSourceEnd := ASourceStart + ALength
|
||||
else
|
||||
FSourceEnd := Cardinal.MaxValue;
|
||||
|
||||
if ADestinationStart >= ASourceStart then
|
||||
begin
|
||||
FDifference1 := ADestinationStart - ASourceStart;
|
||||
FDifference2 := 0;
|
||||
end
|
||||
else begin
|
||||
FDifference1 := 0;
|
||||
FDifference2 := ASourceStart - ADestinationStart;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TAlmanacMapRange.TryConvert(const AInput: Cardinal; out OOutput: Cardinal): Boolean;
|
||||
begin
|
||||
if (FSourceStart <= AInput) and (AInput < FSourceEnd) then
|
||||
begin
|
||||
if FDifference1 > 0 then
|
||||
OOutput := AInput + FDifference1
|
||||
else
|
||||
OOutput := AInput - FDifference2;
|
||||
Result := True;
|
||||
end
|
||||
else begin
|
||||
OOutput := 0;
|
||||
Result := False;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TAlmanacMap }
|
||||
|
||||
constructor TAlmanacMap.Create;
|
||||
begin
|
||||
FRanges := specialize TFPGObjectList<TAlmanacMapRange>.Create;
|
||||
end;
|
||||
|
||||
destructor TAlmanacMap.Destroy;
|
||||
begin
|
||||
FRanges.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TAlmanacMap.AddMapRange(const ALine: string);
|
||||
var
|
||||
split: TStringArray;
|
||||
begin
|
||||
split := ALine.Split(' ');
|
||||
FRanges.Add(TAlmanacMapRange.Create(StrToDWord(split[0]), StrToDWord(split[1]), StrToDWord(split[2])));
|
||||
end;
|
||||
|
||||
function TAlmanacMap.Convert(const AInput: Cardinal): Cardinal;
|
||||
var
|
||||
range: TAlmanacMapRange;
|
||||
begin
|
||||
for range in FRanges do
|
||||
begin
|
||||
if range.TryConvert(AInput, Result) then
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Result := AInput;
|
||||
end;
|
||||
|
||||
{ TGiveSeedFertilizer }
|
||||
|
||||
procedure TGiveSeedFertilizer.ProcessSeeds(const ALine: string);
|
||||
var
|
||||
split: TStringArray;
|
||||
i: Integer;
|
||||
begin
|
||||
split := Aline.Split(' ');
|
||||
for i := 1 to Length(split) - 1 do
|
||||
begin
|
||||
FSeeds.Add(StrToDWord(split[i]));
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TGiveSeedFertilizer.Create;
|
||||
begin
|
||||
FSeeds := specialize TFPGList<Cardinal>.Create;
|
||||
FMaps := specialize TFPGObjectList<TAlmanacMap>.Create;
|
||||
end;
|
||||
|
||||
destructor TGiveSeedFertilizer.Destroy;
|
||||
begin
|
||||
FSeeds.Free;
|
||||
FMaps.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TGiveSeedFertilizer.ProcessDataLine(const ALine: string);
|
||||
begin
|
||||
if LeftStr(ALine, 6) = 'seeds:' then
|
||||
ProcessSeeds(ALine)
|
||||
else if RightStr(ALine, 4) = 'map:' then
|
||||
FMaps.Add(TAlmanacMap.Create)
|
||||
else if Aline <> '' then
|
||||
FMaps.Last.AddMapRange(ALine);
|
||||
end;
|
||||
|
||||
procedure TGiveSeedFertilizer.Finish;
|
||||
var
|
||||
seed, value: Cardinal;
|
||||
map: TAlmanacMap;
|
||||
begin
|
||||
for seed in FSeeds do
|
||||
begin
|
||||
value := seed;
|
||||
for map in FMaps do
|
||||
begin
|
||||
value := map.Convert(value);
|
||||
end;
|
||||
if (FPart1 = 0) or (value < FPart1) then
|
||||
FPart1 := value;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TGiveSeedFertilizer.GetDataFileName: string;
|
||||
begin
|
||||
Result := 'give_seed_fertilizer.txt';
|
||||
end;
|
||||
|
||||
function TGiveSeedFertilizer.GetPuzzleName: string;
|
||||
begin
|
||||
Result := 'Day 5: If You Give A Seed A Fertilizer';
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -52,6 +52,10 @@
|
|||
<Filename Value="UScratchcardsTestCases.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="UGiveSeedFertilizerTestCases.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -3,7 +3,8 @@ program AdventOfCodeFPCUnit;
|
|||
{$mode objfpc}{$H+}
|
||||
|
||||
uses
|
||||
Interfaces, Forms, GuiTestRunner, USolver, UBaseTestCases, UGearRatiosTestCases, UScratchcardsTestCases;
|
||||
Interfaces, Forms, GuiTestRunner, USolver, UBaseTestCases, UGearRatiosTestCases, UScratchcardsTestCases,
|
||||
UGiveSeedFertilizerTestCases;
|
||||
|
||||
{$R *.res}
|
||||
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
{
|
||||
Solutions to the Advent Of Code.
|
||||
Copyright (C) 2023 Stefan Müller
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
}
|
||||
|
||||
unit UGiveSeedFertilizerTestCases;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, fpcunit, testregistry, USolver, UBaseTestCases, UGiveSeedFertilizer;
|
||||
|
||||
type
|
||||
|
||||
{ TGiveSeedFertilizerFullDataTestCase }
|
||||
|
||||
TGiveSeedFertilizerFullDataTestCase = class(TEngineBaseTest)
|
||||
protected
|
||||
function CreateSolver: ISolver; override;
|
||||
published
|
||||
procedure TestPart1;
|
||||
procedure TestPart2;
|
||||
end;
|
||||
|
||||
{ TGiveSeedFertilizerExampleTestCase }
|
||||
|
||||
TGiveSeedFertilizerExampleTestCase = class(TExampleEngineBaseTest)
|
||||
protected
|
||||
function CreateSolver: ISolver; override;
|
||||
published
|
||||
procedure TestPart1;
|
||||
procedure TestPart2;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TGiveSeedFertilizerFullDataTestCase }
|
||||
|
||||
function TGiveSeedFertilizerFullDataTestCase.CreateSolver: ISolver;
|
||||
begin
|
||||
Result := TGiveSeedFertilizer.Create;
|
||||
end;
|
||||
|
||||
procedure TGiveSeedFertilizerFullDataTestCase.TestPart1;
|
||||
begin
|
||||
AssertEquals(51580674, FSolver.GetResultPart1);
|
||||
end;
|
||||
|
||||
procedure TGiveSeedFertilizerFullDataTestCase.TestPart2;
|
||||
begin
|
||||
AssertEquals(-1, FSolver.GetResultPart2);
|
||||
end;
|
||||
|
||||
{ TGiveSeedFertilizerExampleTestCase }
|
||||
|
||||
function TGiveSeedFertilizerExampleTestCase.CreateSolver: ISolver;
|
||||
begin
|
||||
Result := TGiveSeedFertilizer.Create;
|
||||
end;
|
||||
|
||||
procedure TGiveSeedFertilizerExampleTestCase.TestPart1;
|
||||
begin
|
||||
AssertEquals(35, FSolver.GetResultPart1);
|
||||
end;
|
||||
|
||||
procedure TGiveSeedFertilizerExampleTestCase.TestPart2;
|
||||
begin
|
||||
AssertEquals(-1, FSolver.GetResultPart2);
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
||||
RegisterTest(TGiveSeedFertilizerFullDataTestCase);
|
||||
RegisterTest(TGiveSeedFertilizerExampleTestCase);
|
||||
end.
|
Loading…
Reference in New Issue