### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: [SOLVED] Randomizing numbers problem  (Read 758 times)

#### Slyde

• New Member
• Posts: 42
##### [SOLVED] Randomizing numbers problem
« on: November 21, 2020, 08:04:09 pm »
I wrote this

Code: Pascal  [Select][+][-]
1. procedure TForm1.Button1Click(Sender: TObject);
2. var
3.   i, j, f, num : integer;
4.   myArray : array[1..20] of Integer;
5. begin
6.   Randomize;
7.   for i := 1 to 20 do
8.       begin
9.         f := 0;
10.         num := randomrange(0, 19);
11.         for j := 1 to i do
12.           if myArray[j] = num then
13.             f := 1;
14.         if f <> 1 then
15.         begin
16.           myArray[i] := num;
18.         end;
19.       end;
20. end;

and now I'm stuck.  My problem is that I need to subtract from the for-loop i when a random number's in the array, so that it'll dig out all 20 numbers (0 thru 19).
« Last Edit: November 21, 2020, 11:15:57 pm by Slyde »
Linux Mint 20.0 / Lazarus 2.0.10 / FPC 3.2.0
Windows X / Lazarus 2.0.10 / FPC 3.2.0

#### wildfire

• Jr. Member
• Posts: 77
##### Re: Randomizing numbers problem
« Reply #1 on: November 21, 2020, 08:10:18 pm »
If the end requirement is to have an array of randomly stored values 0-19 then you are approaching it from the wrong angle imo.

Fill the array and then randomly swap elements.
Windows 10 64bit version 1809
Laz 2.0.0 FPC 3.0.4

#### Slyde

• New Member
• Posts: 42
##### Re: Randomizing numbers problem
« Reply #2 on: November 21, 2020, 08:26:07 pm »
@wildfire - I wld have to agree with you.  But that's not my endgame.
Linux Mint 20.0 / Lazarus 2.0.10 / FPC 3.2.0
Windows X / Lazarus 2.0.10 / FPC 3.2.0

#### PascalDragon

• Hero Member
• Posts: 2618
• Compiler Developer
##### Re: Randomizing numbers problem
« Reply #3 on: November 21, 2020, 08:35:04 pm »
and now I'm stuck.  My problem is that I need to subtract from the for-loop i when a random number's in the array, so that it'll dig out all 20 numbers (0 thru 19).

What do you mean with "I need to substract from the for-loop i "? What is the result you want to achieve?

By the way: it's cleaner if you declare your f as a Boolean, initialize it with False, inside the check loop set it to True and later on do if f then. Also you can add a Break statement in your check loop once you've found the number:

Code: Pascal  [Select][+][-]
1.         for j := 1 to i do
2.           if myArray[j] = num then begin
3.             f := True;
4.             Break;
5.           end;

#### jamie

• Hero Member
• Posts: 4052
##### Re: Randomizing numbers problem
« Reply #4 on: November 21, 2020, 08:42:46 pm »
maybe he wants an array of 0..19 in value then with that have a  1 - 20 counter where as it uses Random(0,19) as an exchange index of the last random that was used..

basically no need to determine if there is a duplication in there list from a random value, just use the random value as swap indexes.
The only true wisdom is knowing you know nothing

#### Slyde

• New Member
• Posts: 42
##### Re: Randomizing numbers problem
« Reply #5 on: November 21, 2020, 08:46:17 pm »
I need to have an array of 0 to number of records in my SQLite3 Table(s). Since I don't want to have the same Questions spill out in the same order each time, I'll use this array to seed the form with randomly selected questions, based off the array.

And since i increments each pass through the loop, I need to decrease it ( i := i -1) so that it doesn't leave my array void of all 20 numbers.

The code I posted is for my testing. Nothing more.
« Last Edit: November 21, 2020, 08:54:18 pm by Slyde »
Linux Mint 20.0 / Lazarus 2.0.10 / FPC 3.2.0
Windows X / Lazarus 2.0.10 / FPC 3.2.0

#### lucamar

• Hero Member
• Posts: 3455
##### Re: Randomizing numbers problem
« Reply #6 on: November 21, 2020, 09:04:36 pm »
Try this:

Code: Pascal  [Select][+][-]
1. procedure TForm1.Button1Click(Sender: TObject);
2. var
3.   i, num, Count : integer;
4.   myArray : array[1..20] of Integer;
5.
6.   function InArray(num: Integer): Boolean;
7.   var i: Integer;
8.   begin
9.     Result := False;
10.     for i := 1 to Count do begin
11.       Result := myArray[i] = num;
12.       if Result then Break
13.     end;
14.   end;
15.
16. begin
17.   Randomize;
18.   repeat
19.     repeat
20.       num := randomrange(0, 19);
21.     until not InArray(num);
22.     Inc(Count);
23.     myArray[Count] := num;
25.   until Count = Length(myArray);
26. end;

Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!)
Lazarus/FPC 2.0.8/3.0.4 & 2.0.10/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

#### Slyde

• New Member
• Posts: 42
##### Re: Randomizing numbers problem
« Reply #7 on: November 21, 2020, 09:11:50 pm »
@lucamar - It hangs.  I'll study it and see if I can fix it.  Thank you.
Linux Mint 20.0 / Lazarus 2.0.10 / FPC 3.2.0
Windows X / Lazarus 2.0.10 / FPC 3.2.0

#### lucamar

• Hero Member
• Posts: 3455
##### Re: Randomizing numbers problem
« Reply #8 on: November 21, 2020, 09:27:46 pm »
@lucamar - It hangs.  I'll study it and see if I can fix it.  Thank you.

Oops! Forgot to initialize Count
Code: Pascal  [Select][+][-]
1. procedure TForm1.Button1Click(Sender: TObject);
2. var
3.   num, Count : integer;
4.   myArray : array[1..20] of Integer;
5.
6.   function InArray(num: Integer): Boolean;
7.   var i: Integer;
8.   begin
9.     Result := False;
10.     for i := 1 to Count do begin
11.       Result := myArray[i] = num;
12.       if Result then Break
13.     end;
14.   end;
15.
16. begin
17.   Randomize;
18.   Count := 0;
19.   repeat
20.     repeat
21.       num := randomrange(0, 19);
22.     until not InArray(num);
23.     Inc(Count);
24.     myArray[Count] := num;
26.   until Count = Length(myArray);
27. end;

ETA: The attached image seems to show only 10 numbers but that is because I forgot to set the memo's scroll bars
« Last Edit: November 21, 2020, 10:52:04 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!)
Lazarus/FPC 2.0.8/3.0.4 & 2.0.10/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

#### Slyde

• New Member
• Posts: 42
##### Re: Randomizing numbers problem
« Reply #9 on: November 21, 2020, 09:29:00 pm »
Got it.  Had to set Count var to 0:

Code: Pascal  [Select][+][-]
1. begin
2.   Randomize;
3.   Count:=0;
4.   repeat
5.     repeat
6.       num := randomrange(0, 19);
7.     until not InArray(num);
8.     Inc(Count);
9.     myArray[Count] := num;
11.   until Count = Length(myArray);
12. end;

Thanks, lucamar.
Linux Mint 20.0 / Lazarus 2.0.10 / FPC 3.2.0
Windows X / Lazarus 2.0.10 / FPC 3.2.0

#### winni

• Hero Member
• Posts: 2122
##### Re: Randomizing numbers problem
« Reply #10 on: November 21, 2020, 09:35:13 pm »
Hi!

So often forgotten: Sets.

This is a typical situation where it reduces the code.

Come back later when I fixed my  brandnew USB stick.

Winni

#### Slyde

• New Member
• Posts: 42
##### Re: Randomizing numbers problem
« Reply #11 on: November 21, 2020, 10:24:13 pm »
Count, initialized to 0, locks it up. But if I initialize it to 1, it skips a number and only gives 19 of the 20.

I see where you (lucamar) increase Count, but it goes to the function as 0 on first try.  So, is the for-loop locking this up?

Code: Pascal  [Select][+][-]
1. for i := 1 to Count do begin
Linux Mint 20.0 / Lazarus 2.0.10 / FPC 3.2.0
Windows X / Lazarus 2.0.10 / FPC 3.2.0

#### Roland57

• Full Member
• Posts: 115
##### Re: Randomizing numbers problem
« Reply #12 on: November 21, 2020, 10:31:03 pm »
Hello! Another proposition. (I hope I correctly understood what you need.)

Code: Pascal  [Select][+][-]
1. type
2.   TIntArray = array of integer;
3.
4. function Pick(var a: TIntArray): integer;
5. var
6.   i: integer;
7. begin
8.   i := Random(Length(a));
9.   result := a[i];
10.   a[i] := a[Pred(Length(a))];
11.   SetLength(a, Pred(Length(a)));
12. end;
13.
14. var
15.   a: TIntArray;
16.   i: integer;
17.
18. begin
19.   Randomize;
20.   SetLength(a, 20);
21.   for i := 0 to 19 do
22.     a[i] := i;
23.   for i := 0 to 19 do
24.     WriteLn(Pick(a));
25. end.
26.

#### jamie

• Hero Member
• Posts: 4052
##### Re: Randomizing numbers problem
« Reply #13 on: November 21, 2020, 10:32:13 pm »
this is my version

Code: Pascal  [Select][+][-]
1. procedure TForm1.Button1Click(Sender: TObject);
2. Var
3.   i:integer;
4.   A:Array[0..19]of Integer;
5.      Procedure Exchange(J,K:Integer);
6.       Var
7.         C,D:Integer;
8.       Begin
9.         C := A[J];D:=A[k];
10.         A[J] :=D;
11.         A[K] :=C;
12.       End;
13. begin
14.   Memo1.Lines.Clear;
15.   For I := 0 to 19 do A[I] := I+1; //Test load an array with 1..20 numbers
16.   //--
17.   For I := 0 to 19 Do
18.      Exchange(I,Random(19));
19.
20.   For I := 0 to 19 do memo1.Lines.Add(IntToStr(A[I]));  //display results
21. end;
22.
23.

This does not dead lock because it just takes what it has but the available numbers are predefined so all that needs to be done is mixed up the array of them without searching for duplicates. etc
The only true wisdom is knowing you know nothing

#### lucamar

• Hero Member
• Posts: 3455
##### Re: Randomizing numbers problem
« Reply #14 on: November 21, 2020, 10:40:51 pm »
I see where you (lucamar) increase Count, but it goes to the function as 0 on first try.  So, is the for-loop locking this up?

No, in that case the for loop won't execute at all so the function will return False. The "until" test then becomes "not False", which is True, so the execution will go on and add the very first number to the array.

It works as it should here.
« Last Edit: November 21, 2020, 10:50:33 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!)
Lazarus/FPC 2.0.8/3.0.4 & 2.0.10/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.