Refactored TPointOfIncidence to better unify the algorithm for both parts
This commit is contained in:
parent
307eb14b55
commit
01267c8f79
|
@ -31,7 +31,8 @@ type
|
|||
|
||||
TMirrorCandidate = record
|
||||
Position: Integer;
|
||||
HasFix: Boolean;
|
||||
IsFixAllowed: Boolean;
|
||||
Part: Integer;
|
||||
end;
|
||||
|
||||
TMirrorCandidates = specialize TList<TMirrorCandidate>;
|
||||
|
@ -41,19 +42,17 @@ type
|
|||
TPointOfIncidence = class(TSolver)
|
||||
private
|
||||
FLines: TStringList;
|
||||
FHorizontalMirrorCandidates, FVerticalMirrorCandidates: specialize TList<Integer>;
|
||||
FHorizontalFixedMirrorCandidates, FVerticalFixedMirrorCandidates: TMirrorCandidates;
|
||||
FHorizontalMirrorCandidates, FVerticalMirrorCandidates: TMirrorCandidates;
|
||||
procedure ProcessPatternLine(const ALine: string);
|
||||
procedure VerifyHorizontalCandidates(const ANewLine: string);
|
||||
procedure VerifyHorizontalFixedCandidates(const ANewLine: string);
|
||||
procedure CheckForNewHorizontalCandidate(const ANewLine: string);
|
||||
function HaveSingleDifference(const ALine1, ALine2: string): Boolean;
|
||||
procedure VerifyVerticalCandidates(const ALine: string);
|
||||
procedure VerifyVerticalFixedCandidates(const ALine: string);
|
||||
procedure InitializeNewVerticalCandidates(const AFirstLine: string);
|
||||
function IsVerticalMirrorOfLine(const ALine: string; const AMirror: Integer): TMirrorCompareResult;
|
||||
procedure FinishPattern;
|
||||
function GetMirrorCandidate(const APosition: Integer; const AHasFix: Boolean): TMirrorCandidate;
|
||||
function GetMirrorCandidate(const APosition: Integer; const AIsFixAllowed: Boolean; const APart: Integer):
|
||||
TMirrorCandidate;
|
||||
procedure SetMirrorCandidateFixed(const AMirrorCandidates: TMirrorCandidates; const AIndex: Integer);
|
||||
public
|
||||
constructor Create;
|
||||
|
@ -71,14 +70,10 @@ implementation
|
|||
procedure TPointOfIncidence.ProcessPatternLine(const ALine: string);
|
||||
begin
|
||||
VerifyHorizontalCandidates(ALine);
|
||||
VerifyHorizontalFixedCandidates(ALine);
|
||||
CheckForNewHorizontalCandidate(ALine);
|
||||
|
||||
if FLines.Count > 0 then
|
||||
begin
|
||||
VerifyVerticalCandidates(ALine);
|
||||
VerifyVerticalFixedCandidates(ALine);
|
||||
end
|
||||
VerifyVerticalCandidates(ALine)
|
||||
else
|
||||
InitializeNewVerticalCandidates(ALine);
|
||||
|
||||
|
@ -94,32 +89,16 @@ begin
|
|||
while i >= 0 do
|
||||
begin
|
||||
// Calculates the index of the line that the current line would be a duplicate of in regards to the i-th candidate.
|
||||
mirroredIndex := 2 * FHorizontalMirrorCandidates[i] - FLines.Count - 1;
|
||||
if (mirroredIndex >= 0) and (ANewLine <> FLines[mirroredIndex]) then
|
||||
FHorizontalMirrorCandidates.Delete(i);
|
||||
Dec(i);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPointOfIncidence.VerifyHorizontalFixedCandidates(const ANewLine: string);
|
||||
var
|
||||
i, mirroredIndex: Integer;
|
||||
begin
|
||||
// Checks if the current line fulfills the exisiting horizontal mirror candidates.
|
||||
i := FHorizontalFixedMirrorCandidates.Count - 1;
|
||||
while i >= 0 do
|
||||
begin
|
||||
// Calculates the index of the line that the current line would be a duplicate of in regards to the i-th candidate.
|
||||
mirroredIndex := 2 * FHorizontalFixedMirrorCandidates[i].Position - FLines.Count - 1;
|
||||
mirroredIndex := 2 * FHorizontalMirrorCandidates[i].Position - FLines.Count - 1;
|
||||
if mirroredIndex >= 0 then
|
||||
begin
|
||||
if ANewLine <> FLines[mirroredIndex] then
|
||||
begin
|
||||
if not FHorizontalFixedMirrorCandidates[i].HasFix
|
||||
if FHorizontalMirrorCandidates[i].IsFixAllowed
|
||||
and HaveSingleDifference(ANewLine, FLines[mirroredIndex]) then
|
||||
SetMirrorCandidateFixed(FHorizontalFixedMirrorCandidates, i)
|
||||
SetMirrorCandidateFixed(FHorizontalMirrorCandidates, i)
|
||||
else
|
||||
FHorizontalFixedMirrorCandidates.Delete(i);
|
||||
FHorizontalMirrorCandidates.Delete(i);
|
||||
end;
|
||||
end;
|
||||
Dec(i);
|
||||
|
@ -133,11 +112,11 @@ begin
|
|||
begin
|
||||
if ANewLine = FLines[FLines.Count - 1] then
|
||||
begin
|
||||
FHorizontalMirrorCandidates.Add(FLines.Count);
|
||||
FHorizontalFixedMirrorCandidates.Add(GetMirrorCandidate(FLines.Count, False));
|
||||
FHorizontalMirrorCandidates.Add(GetMirrorCandidate(FLines.Count, False, 1));
|
||||
FHorizontalMirrorCandidates.Add(GetMirrorCandidate(FLines.Count, True, 2));
|
||||
end
|
||||
else if HaveSingleDifference(ANewLine, FLines[FLines.Count - 1]) then
|
||||
FHorizontalFixedMirrorCandidates.Add(GetMirrorCandidate(FLines.Count, True));
|
||||
FHorizontalMirrorCandidates.Add(GetMirrorCandidate(FLines.Count, False, 2));
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -171,27 +150,14 @@ begin
|
|||
i := FVerticalMirrorCandidates.Count - 1;
|
||||
while i >= 0 do
|
||||
begin
|
||||
if IsVerticalMirrorOfLine(ALine, FVerticalMirrorCandidates[i]) <> mcSame then
|
||||
FVerticalMirrorCandidates.Delete(i);
|
||||
Dec(i);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPointOfIncidence.VerifyVerticalFixedCandidates(const ALine: string);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
i := FVerticalFixedMirrorCandidates.Count - 1;
|
||||
while i >= 0 do
|
||||
begin
|
||||
case IsVerticalMirrorOfLine(ALine, FVerticalFixedMirrorCandidates[i].Position) of
|
||||
case IsVerticalMirrorOfLine(ALine, FVerticalMirrorCandidates[i].Position) of
|
||||
mcOneDifference:
|
||||
if FVerticalFixedMirrorCandidates[i].HasFix then
|
||||
FVerticalFixedMirrorCandidates.Delete(i)
|
||||
if FVerticalMirrorCandidates[i].IsFixAllowed then
|
||||
SetMirrorCandidateFixed(FVerticalMirrorCandidates, i)
|
||||
else
|
||||
SetMirrorCandidateFixed(FVerticalFixedMirrorCandidates, i);
|
||||
FVerticalMirrorCandidates.Delete(i);
|
||||
mcDifferent:
|
||||
FVerticalFixedMirrorCandidates.Delete(i);
|
||||
FVerticalMirrorCandidates.Delete(i);
|
||||
end;
|
||||
Dec(i);
|
||||
end;
|
||||
|
@ -205,11 +171,11 @@ begin
|
|||
for i := 1 to Length(AFirstLine) - 1 do
|
||||
case IsVerticalMirrorOfLine(AFirstLine, i) of
|
||||
mcSame: begin
|
||||
FVerticalMirrorCandidates.Add(i);
|
||||
FVerticalFixedMirrorCandidates.Add(GetMirrorCandidate(i, False));
|
||||
FVerticalMirrorCandidates.Add(GetMirrorCandidate(i, False, 1));
|
||||
FVerticalMirrorCandidates.Add(GetMirrorCandidate(i, True, 2));
|
||||
end;
|
||||
mcOneDifference:
|
||||
FVerticalFixedMirrorCandidates.Add(GetMirrorCandidate(i, True));
|
||||
FVerticalMirrorCandidates.Add(GetMirrorCandidate(i, False, 2));
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -237,28 +203,32 @@ var
|
|||
i: Integer;
|
||||
begin
|
||||
for i := 0 to FHorizontalMirrorCandidates.Count - 1 do
|
||||
Inc(FPart1, FHorizontalMirrorCandidates[i] * 100);
|
||||
for i := 0 to FVerticalMirrorCandidates.Count - 1 do
|
||||
Inc(FPart1, FVerticalMirrorCandidates[i]);
|
||||
begin
|
||||
if FHorizontalMirrorCandidates[i].Part = 1 then
|
||||
Inc(FPart1, FHorizontalMirrorCandidates[i].Position * 100)
|
||||
else if not FHorizontalMirrorCandidates[i].IsFixAllowed then
|
||||
Inc(FPart2, FHorizontalMirrorCandidates[i].Position * 100);
|
||||
end;
|
||||
|
||||
for i := 0 to FHorizontalFixedMirrorCandidates.Count - 1 do
|
||||
if FHorizontalFixedMirrorCandidates[i].HasFix then
|
||||
Inc(FPart2, FHorizontalFixedMirrorCandidates[i].Position * 100);
|
||||
for i := 0 to FVerticalFixedMirrorCandidates.Count - 1 do
|
||||
if FVerticalFixedMirrorCandidates[i].HasFix then
|
||||
Inc(FPart2, FVerticalFixedMirrorCandidates[i].Position);
|
||||
for i := 0 to FVerticalMirrorCandidates.Count - 1 do
|
||||
begin
|
||||
if FVerticalMirrorCandidates[i].Part = 1 then
|
||||
Inc(FPart1, FVerticalMirrorCandidates[i].Position)
|
||||
else if not FVerticalMirrorCandidates[i].IsFixAllowed then
|
||||
Inc(FPart2, FVerticalMirrorCandidates[i].Position);
|
||||
end;
|
||||
|
||||
FLines.Clear;
|
||||
FHorizontalMirrorCandidates.Clear;
|
||||
FVerticalMirrorCandidates.Clear;
|
||||
FHorizontalFixedMirrorCandidates.Clear;
|
||||
FVerticalFixedMirrorCandidates.Clear;
|
||||
end;
|
||||
|
||||
function TPointOfIncidence.GetMirrorCandidate(const APosition: Integer; const AHasFix: Boolean): TMirrorCandidate;
|
||||
function TPointOfIncidence.GetMirrorCandidate(const APosition: Integer; const AIsFixAllowed: Boolean; const APart:
|
||||
Integer): TMirrorCandidate;
|
||||
begin
|
||||
Result.Position := APosition;
|
||||
Result.HasFix := AHasFix;
|
||||
Result.IsFixAllowed := AIsFixAllowed;
|
||||
Result.Part := APart;
|
||||
end;
|
||||
|
||||
procedure TPointOfIncidence.SetMirrorCandidateFixed(const AMirrorCandidates: TMirrorCandidates; const AIndex: Integer);
|
||||
|
@ -266,17 +236,15 @@ var
|
|||
mirrorCandidate: TMirrorCandidate;
|
||||
begin
|
||||
mirrorCandidate := AMirrorCandidates[AIndex];
|
||||
mirrorCandidate.HasFix := True;
|
||||
mirrorCandidate.IsFixAllowed := False;
|
||||
AMirrorCandidates[AIndex] := mirrorCandidate;
|
||||
end;
|
||||
|
||||
constructor TPointOfIncidence.Create;
|
||||
begin
|
||||
FLines := TStringList.Create;
|
||||
FHorizontalMirrorCandidates := specialize TList<Integer>.Create;
|
||||
FVerticalMirrorCandidates := specialize TList<Integer>.Create;
|
||||
FHorizontalFixedMirrorCandidates := TMirrorCandidates.Create;
|
||||
FVerticalFixedMirrorCandidates := TMirrorCandidates.Create;
|
||||
FHorizontalMirrorCandidates := TMirrorCandidates.Create;
|
||||
FVerticalMirrorCandidates := TMirrorCandidates.Create;
|
||||
end;
|
||||
|
||||
destructor TPointOfIncidence.Destroy;
|
||||
|
@ -284,8 +252,6 @@ begin
|
|||
FLines.Free;
|
||||
FHorizontalMirrorCandidates.Free;
|
||||
FVerticalMirrorCandidates.Free;
|
||||
FHorizontalFixedMirrorCandidates.Free;
|
||||
FVerticalFixedMirrorCandidates.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
|
|
Loading…
Reference in New Issue