From 01267c8f79ef2c043236aca1ea902d881d8aeaa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20M=C3=BCller?= Date: Thu, 14 Dec 2023 00:52:28 +0100 Subject: [PATCH] Refactored TPointOfIncidence to better unify the algorithm for both parts --- solvers/UPointOfIncidence.pas | 116 ++++++++++++---------------------- 1 file changed, 41 insertions(+), 75 deletions(-) diff --git a/solvers/UPointOfIncidence.pas b/solvers/UPointOfIncidence.pas index 42d4c34..42e3939 100644 --- a/solvers/UPointOfIncidence.pas +++ b/solvers/UPointOfIncidence.pas @@ -31,7 +31,8 @@ type TMirrorCandidate = record Position: Integer; - HasFix: Boolean; + IsFixAllowed: Boolean; + Part: Integer; end; TMirrorCandidates = specialize TList; @@ -41,19 +42,17 @@ type TPointOfIncidence = class(TSolver) private FLines: TStringList; - FHorizontalMirrorCandidates, FVerticalMirrorCandidates: specialize TList; - 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.Create; - FVerticalMirrorCandidates := specialize TList.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;