Updated solution for "Day 5: If You Give A Seed A Fertilizer", part 1, to process the data just in time instead of preloading all of it
This commit is contained in:
parent
e68701333b
commit
474cfa6cc3
|
@ -32,29 +32,19 @@ type
|
||||||
private
|
private
|
||||||
FDestinationStart, FSourceStart, FSourceEnd, FDifference1, FDifference2: Cardinal;
|
FDestinationStart, FSourceStart, FSourceEnd, FDifference1, FDifference2: Cardinal;
|
||||||
public
|
public
|
||||||
|
constructor Create(const ALine: string);
|
||||||
constructor Create(const ADestinationStart, ASourceStart, ALength: Cardinal);
|
constructor Create(const ADestinationStart, ASourceStart, ALength: Cardinal);
|
||||||
function TryConvert(const AInput: Cardinal; out OOutput: Cardinal): Boolean;
|
function TryConvert(const AInput: Cardinal; out OOutput: Cardinal): Boolean;
|
||||||
end;
|
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 }
|
||||||
|
|
||||||
TGiveSeedFertilizer = class(TSolver)
|
TGiveSeedFertilizer = class(TSolver)
|
||||||
private
|
private
|
||||||
FSeeds: specialize TFPGList<Cardinal>;
|
FNew, FConverted, FProcessedIndices: specialize TFPGList<Cardinal>;
|
||||||
FMaps: specialize TFPGObjectList<TAlmanacMap>;
|
|
||||||
procedure ProcessSeeds(const ALine: string);
|
procedure ProcessSeeds(const ALine: string);
|
||||||
|
procedure ProcessMapRange(const ALine: string);
|
||||||
|
procedure FinishMap;
|
||||||
public
|
public
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
@ -68,6 +58,14 @@ implementation
|
||||||
|
|
||||||
{ TAlmanacMapRange }
|
{ TAlmanacMapRange }
|
||||||
|
|
||||||
|
constructor TAlmanacMapRange.Create(const ALine: string);
|
||||||
|
var
|
||||||
|
split: TStringArray;
|
||||||
|
begin
|
||||||
|
split := ALine.Split(' ');
|
||||||
|
Create(StrToDWord(split[0]), StrToDWord(split[1]), StrToDWord(split[2]));
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TAlmanacMapRange.Create(const ADestinationStart, ASourceStart, ALength: Cardinal);
|
constructor TAlmanacMapRange.Create(const ADestinationStart, ASourceStart, ALength: Cardinal);
|
||||||
begin
|
begin
|
||||||
FDestinationStart := ADestinationStart;
|
FDestinationStart := ADestinationStart;
|
||||||
|
@ -106,40 +104,6 @@ begin
|
||||||
end;
|
end;
|
||||||
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 }
|
{ TGiveSeedFertilizer }
|
||||||
|
|
||||||
procedure TGiveSeedFertilizer.ProcessSeeds(const ALine: string);
|
procedure TGiveSeedFertilizer.ProcessSeeds(const ALine: string);
|
||||||
|
@ -150,20 +114,60 @@ begin
|
||||||
split := Aline.Split(' ');
|
split := Aline.Split(' ');
|
||||||
for i := 1 to Length(split) - 1 do
|
for i := 1 to Length(split) - 1 do
|
||||||
begin
|
begin
|
||||||
FSeeds.Add(StrToDWord(split[i]));
|
FNew.Add(StrToDWord(split[i]));
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TGiveSeedFertilizer.ProcessMapRange(const ALine: string);
|
||||||
|
var
|
||||||
|
range: TAlmanacMapRange;
|
||||||
|
i: Integer;
|
||||||
|
converted: Cardinal;
|
||||||
|
begin
|
||||||
|
// Converts all "new" values that fall into this mapping range.
|
||||||
|
range := TAlmanacMapRange.Create(ALine);
|
||||||
|
for i := 0 to FNew.Count - 1 do
|
||||||
|
begin
|
||||||
|
if range.TryConvert(FNew[i], converted) then
|
||||||
|
begin
|
||||||
|
FConverted.Add(converted);
|
||||||
|
FProcessedIndices.Add(i);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
range.Free;
|
||||||
|
|
||||||
|
// Forgets the converted values.
|
||||||
|
for i := FProcessedIndices.Count - 1 downto 0 do
|
||||||
|
begin
|
||||||
|
FNew.Delete(FProcessedIndices[i]);
|
||||||
|
end;
|
||||||
|
FProcessedIndices.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGiveSeedFertilizer.FinishMap;
|
||||||
|
var
|
||||||
|
value: Cardinal;
|
||||||
|
begin
|
||||||
|
// Resets the lists for the next map, remaining values stay unconverted.
|
||||||
|
for value in FConverted do
|
||||||
|
begin
|
||||||
|
FNew.Add(value);
|
||||||
|
end;
|
||||||
|
FConverted.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TGiveSeedFertilizer.Create;
|
constructor TGiveSeedFertilizer.Create;
|
||||||
begin
|
begin
|
||||||
FSeeds := specialize TFPGList<Cardinal>.Create;
|
FNew := specialize TFPGList<Cardinal>.Create;
|
||||||
FMaps := specialize TFPGObjectList<TAlmanacMap>.Create;
|
FConverted := specialize TFPGList<Cardinal>.Create;
|
||||||
|
FProcessedIndices := specialize TFPGList<Cardinal>.Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TGiveSeedFertilizer.Destroy;
|
destructor TGiveSeedFertilizer.Destroy;
|
||||||
begin
|
begin
|
||||||
FSeeds.Free;
|
FNew.Free;
|
||||||
FMaps.Free;
|
FConverted.Free;
|
||||||
|
FProcessedIndices.Free;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -172,23 +176,18 @@ begin
|
||||||
if LeftStr(ALine, 6) = 'seeds:' then
|
if LeftStr(ALine, 6) = 'seeds:' then
|
||||||
ProcessSeeds(ALine)
|
ProcessSeeds(ALine)
|
||||||
else if RightStr(ALine, 4) = 'map:' then
|
else if RightStr(ALine, 4) = 'map:' then
|
||||||
FMaps.Add(TAlmanacMap.Create)
|
FinishMap
|
||||||
else if Aline <> '' then
|
else if Aline <> '' then
|
||||||
FMaps.Last.AddMapRange(ALine);
|
ProcessMapRange(ALine);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TGiveSeedFertilizer.Finish;
|
procedure TGiveSeedFertilizer.Finish;
|
||||||
var
|
var
|
||||||
seed, value: Cardinal;
|
value: Cardinal;
|
||||||
map: TAlmanacMap;
|
|
||||||
begin
|
begin
|
||||||
for seed in FSeeds do
|
FinishMap;
|
||||||
|
for value in FNew do
|
||||||
begin
|
begin
|
||||||
value := seed;
|
|
||||||
for map in FMaps do
|
|
||||||
begin
|
|
||||||
value := map.Convert(value);
|
|
||||||
end;
|
|
||||||
if (FPart1 = 0) or (value < FPart1) then
|
if (FPart1 = 0) or (value < FPart1) then
|
||||||
FPart1 := value;
|
FPart1 := value;
|
||||||
end;
|
end;
|
||||||
|
|
Loading…
Reference in New Issue