In order to reduce the number of loops you are doing I recomend you start using sets for storing the posible candidates instead of arrays. Why? Becouse this way you alow yourself to the use of set operators. In your case you are interested in intersection of two sets as this returns you another set that conatins only those elements that are present in all sets. Yes you can find duplicate elements in multiple sets with a single command.
Check this quick code to see an example of how to do this:
Code:
type
TCandidates = set of 1..9;
...
procedure TForm2.Button1Click(Sender: TObject);
var Candidates1, Candidates2, Candidates3: TCandidates;
Duplicates: TCandidates;
Candidate: Integer;
begin
Candidates1 := [3,4,6,7];
Candidates2 := [3,4,5,6,8];
Candidates3 := [4,6];
Memo1.Lines.Add('Intersection between Candidate1 and Candidates2');
Duplicates := Candidates1 * Candidates2;
for Candidate in Duplicates do
begin
Memo1.Lines.Add(IntToStr(Candidate));
end;
Memo1.Lines.Add('Intersection between Candidate1, Candidates2 and Candidates3');
Duplicates := Candidates1 * Candidates2 * Candidates3;
for Candidate in Duplicates do
begin
Memo1.Lines.Add(IntToStr(Candidate));
end;
end;
I belive that using of sets would come quite usefull even in other approaches.
EDIT: In order to be able to use for in loops you need to use Delphi 2005 or newer or FPC 2.4.2 or newer.
EDIT2: And for all those of you who still might be using older Delphi version or other pascal compilers which doesn't support for in loops you first need to declare colection of all posible items in your set and then declare set of that colection like so:
Code:
type
TCandidate = 1..9;
TSetOfCandidates = set of TCandidate;
And then you need to loop through your colection of posible items and test for each on if it is present in your set like so:
Code:
procedure TForm3.Button1Click(Sender: TObject);
var Candidates: TSetOfCandidates;
Candidate: TCandidate;
begin
Candidates := [1,5,7];
for Candidate := Low(Candidate) to High(Candidate) do
begin
if Candidate in Candidates then Memo1.Lines.Add(IntToStr(Candidate));
end;
end;
Yes this is quite messy and performance ineficient especially if you are working with sets that can have large number of posible elements.
Just imagine you have to loop through a set that can conatin all 16 bit unsigned integer values (all 65536 of them) and you have to test for each to see if it is present in your desired set. Doing something like this could take ages.
Bookmarks