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