Hello, guys!

I have to generate 10 different numbers.
What I do is to store the generated numbers in array.
Before that I check the array for duplicates.

It compiles, but I get some duplicates.
Thanks in advance for any help.

program rand;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  j, i, a, m: integer;
  number: array[1..10] of integer;
  included: boolean;

begin
  j := 1;
  m := 1;

  while j < 11 do
  begin
    randomize;
    a := random(11);

    // Checking array for duplicates.
    for i := 1 to 10 do
    begin
      if (number[i] = a) or (a=0) then
      begin
        included := true;
      end
      else
      begin
        included := false;
      end; {if loop}
    end; {for loop}

    // Adding number to array.
    if not included then
    begin
      number[m] := a;
      m := m + 1;
      j := j + 1;
    end; {if loop}
  end; {while loop}

  // Printing out all numbers in array.
  for i := 1 to 10 do
  begin
    writeln(number[i]);
  end;
  readln;
end.

The problem is that, apparently, what you really want is a permutation - it looks like you want only 10 random numbers between 1 and 10. There are any number of ways to do this. One is to go to jsoftware.com, download and install J, then type "1+10?10" in a session.

However, since this is a "Pascal and Delphi" forum, the answer will be substantially more complicated than this.

Here's my guess, allowing for my lack of Pascal knowledge: initialize the array of numbers 1 to 10, then loop through, say 10 times (this is probably overkill), swapping numbers randomly, something like this code fragment:

for i := 1 to 10 do
begin
number = i;
end; (for loop)
for i := 1 to 10 do
begin
ix1 := 1+random(10);
ix2 := 1+random(10);
svnum := number[ix1];
number[ix1] := number[ix2];
number[ix2] := svnum;
end; (for loop)

Since you're swapping (roughly) 2 each time, you could shorten the loop to as little as 5 - somewhere between 5 and 10 would be optimal.

SysUtils is a turbo pascal unit?

Member Avatar for Micheus

It compiles, but I get some duplicates.

Hi simps0n,

Without taking in consideration any others questions, You must to call randomize procedure just an once time in Your project (take a look in help about it).

So, put the call to this procedure before while .. do scope, like this:

...
m := 1;
randomize;
while j < 11 do
begin
  a := random(11);
...

Bye

What is also happening in your code, is that when you find a duplicate, you are setting included to True, but are not exiting your loop and the next number in the array is not a duplicate, so included is set back to false.
You just add an additional line to exit the loop when included is set to true.

// Checking array for duplicates.
for i := 1 to 10 do
begin
  if (number[i] = a) or (a=0) then
  begin
     included := true;
     exit;
  end
  else
  begin
     included := false;
  end; {if loop}
end; {for loop}

Just a bit about the begin ... end in your code -

You only need to wrap the commands in those if there is more than one command to be performed - in the above example, if the test is true you are going to perform 2 or more commands, so you need the begin ... end. If it is false, you are running only one command, so you don't need them, so the code could look like this:

// Checking array for duplicates.
for i := 1 to 10 do
begin
  if (number[i] = a) or (a=0) then
  begin
     included := true;
     exit;
  end
  else included := false; {end if loop}
end; {for loop}

Thank you all, guys!
Really appreciated.

Thank you all, guys!
Really appreciated.

I hope you noticed, though no one commented on it, that the suggestion I made scales much better than the original algorithm. That is, if you're doing this for 10,000 numbers instead of 10, the original algorithm will take about a million times as long versus about a thousand times as long for what I proposed.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.