• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 150
  • Last Modified:

Logic Problem

hi ... if i've got a set of numbers say "123", how the shortest formula to
resulting the permutation of them to be : "123","132","213","231","312","321"? the result could be flexible depends on the length of numbers, right?


0
powerfool
Asked:
powerfool
  • 7
  • 6
  • 5
  • +4
1 Solution
 
ITugayCommented:
Hi,
the working sample is bellow:


type
  TForm1 = class(TForm)
    LB: TListBox;
    SpeedButton1: TSpeedButton;
    procedure SpeedButton1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function GenVariant(aBase,aWork : string) : string;
var I : integer;
begin
  if aWork = '' then Form1.LB.Items.Add(aBase) else
  for I:=1 to length(aWork) do
  begin
    result:=aWork;
    delete(result,I,1);
    GenVariant(aBase+aWork[I],result);
  end;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  GenVariant('','123');
end;


-----
Igor.
0
 
Grayl1Commented:
Hi!

Do you want just one random combination or all of them?
0
 
mullet_attackCommented:
Hey Igor, nice code :-)
0
Take Control of Web Hosting For Your Clients

As a web developer or IT admin, successfully managing multiple client accounts can be challenging. In this webinar we will look at the tools provided by Media Temple and Plesk to make managing your clients’ hosting easier.

 
sagerydCommented:
Nice code Igor, but how does it really work?
0
 
sagerydCommented:
Just a tip:

if n is the number of characters in the input string, then n! is the number of possible combinations.


--johan
0
 
powerfoolAuthor Commented:
that's a good logic, is there anyone could give other alternative? I will give my point in few next days ok ...
thanks to igor.
0
 
ITugayCommented:
Hi all,
I will try to explain my logic. It's very easy;)

To make all combination from the string you need to iterate through all characters in string.  
.....
 for I:=1 to length(aWork) do
.....
then you need to extract (delete) current character and iterate through remain of the string.
.....
    result:=aWork;     // I use "result" as undeclared variable
    delete(result,I,1); // result keep remain of the string
    GenVariant(aBase+aWork[I],result); // recursive call to iterate with remain of the string
    // first parameter keep characters extracted in previous iterations
.....

That's all. It more easy to understand under debugger watching on aBase and aWork parameters.

-----
Igor

PS: if you need not recursive logic then let me know.
0
 
sagerydCommented:
Well....I can't exactly say I understood more of it when you explained but I guess I'll understand it when I debug it in Delphi. Great code though! Good work, Igor!

--johan
0
 
ITugayCommented:
Hi all,
there is another one combinator (not recursive and standalone):


type

  TStrCombintor = class(TObject)
     fCNT : array of integer;
     fIDX : integer;
     procedure   Init(const V : string);
     procedure   RollData(var V : string; Index : integer);
     function    NextCombination(var V : string) : boolean;
  end;

......

procedure TStrCombintor.Init(const V : string);
begin
   SetLength(fCNT,length(V));
   fIDX:=0;
end;

procedure TStrCombintor.RollData(var V : string; Index : integer);
var I  : integer;
    C  : char;
begin
   C:=V[1];
   for I:=1 to Index+1 do V[I]:=V[I+1];
   V[Index+1]:=C;
end;

function TStrCombintor.NextCombination(var V : string) : boolean;
begin
    while fCNT[fIDX]>=fIDX+1 do
    begin
       RollData(V,fIDX+1);
       fCNT[fIDX]:=0;
       inc(fIDX);
    end;
    if fIDX < length(V)-1 then
    begin
      RollData(V,fIDX+1);
      inc(fCNT[fIDX]);
      fIDX:=0;
      result:=true;
    end else result:=false;
end;
---------------

and example how to use it:


procedure TForm1.SpeedButton1Click(Sender: TObject);
var SC : TStrCombintor;
    S  : string;
begin
  S  := '1234';
  SC := TStrCombintor.Create;
  SC.Init(S);
  repeat
    ListBox1.Items.Add(S);
  until not SC.NextCombination(S);
  SC.Free;
end;


-----
Igor
0
 
ITugayCommented:
Hi,

and another one (not recursive):
-----

procedure MutateStr(S : string);
var C : array of integer;
    I : integer;
begin
   SetLength(C,Length(S)-1);
   I:=0;
   repeat
     insert(S[1],S,I+3);
     delete(S,1,1);
     inc(C[I]);
     if C[I]=I+2 then
     begin
       C[I]:=0;
       inc(I);
     end else
     begin
       I:=0;
       Form1.LB.Items.Add(S)
     end;
   until I = Length(S)-1;
end;

-----
It doesn't show initial combination, only all another. Do not pass string with length < 2;)
-----
Igor.
0
 
wuyinzhiCommented:
hi igor, i tried your code above with Delphi 3 and found error at this line:

var C : array of integer;

i suppose you didn't put the index of array?

0
 
ITugayCommented:
hi wuyinzhi,

this code for D5 you need to change

------OLD----- (D5)
var C : array of integer;
      I : integer;
begin
     SetLength(C,Length(S)-1);

----NEW---- (D3)
var C : array [0..255]  of integer;
      I : integer;
begin
     FillChar(C,SizeOf(C),#0);

------------

enjoy;)
-----
Igor
0
 
JohnnyBoyCommented:
Isn't it


counter = length of data
for iLoop = 1 to counter
  answer = answer * counter
0
 
powerfoolAuthor Commented:
hi JohnnyBoy, I don't think your "answer" is an answer for the question, please refer to ITugay's program, he's got best solution so far.

0
 
sagerydCommented:
Why don't we end this thread? Igor has come up with many different variants of the code, propose an answer and end the thread, Igor!

--j exposing his thoughts...
0
 
ITugayCommented:
I wouldn't like to propose an answer. May be another experts have interest solutions. And it's decigion of questioner to accept comment as answer.
;-)

Igor
0
 
sagerydCommented:
Ok! I was just, as I said, exposing my current thought! ;o)

johan
0
 
powerfoolAuthor Commented:
i already accepted igor's comment as right answer and gave my points. how could I do to lock this thread?
0
 
sagerydCommented:
No you haven't!
0
 
ITugayCommented:
hi powerfool,
If you like my answers then just click on "accept comment as answer" ;)
Igor.
0
 
powerfoolAuthor Commented:
Comment accepted as answer
0
 
powerfoolAuthor Commented:
Ok. I do it now.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 7
  • 6
  • 5
  • +4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now