Recent

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

Slyde

  • Full Member
  • ***
  • Posts: 152
[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;
  17.           Memo1.Lines.Add(inttostr(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 21.3
Lazarus 3.0

wildfire

  • Full Member
  • ***
  • Posts: 109
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.
A halo is a mere circle, when does it end?

Slyde

  • Full Member
  • ***
  • Posts: 152
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 21.3
Lazarus 3.0

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • 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: 6090
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

  • Full Member
  • ***
  • Posts: 152
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 21.3
Lazarus 3.0

lucamar

  • Hero Member
  • *****
  • Posts: 4219
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;
  24.     Memo1.Lines.Add(inttostr(num));
  25.   until Count = Length(myArray);
  26. end;

 

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

Slyde

  • Full Member
  • ***
  • Posts: 152
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 21.3
Lazarus 3.0

lucamar

  • Hero Member
  • *****
  • Posts: 4219
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;
  25.     Memo1.Lines.Add(inttostr(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 !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Slyde

  • Full Member
  • ***
  • Posts: 152
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;
  10.     Memo1.Lines.Add(inttostr(num));
  11.   until Count = Length(myArray);
  12. end;

Thanks, lucamar.
Linux Mint 21.3
Lazarus 3.0

winni

  • Hero Member
  • *****
  • Posts: 3197
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

  • Full Member
  • ***
  • Posts: 152
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 21.3
Lazarus 3.0

Roland57

  • Sr. Member
  • ****
  • Posts: 419
    • msegui.net
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.  
My projects are on Gitlab and on Codeberg.

jamie

  • Hero Member
  • *****
  • Posts: 6090
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: 4219
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 !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

 

TinyPortal © 2005-2018