Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Choosing 3 numbers by random....process is yet too slow...how can I speed it up?

Tomfox Wiranata
Registered User
Join date: 20 Dec 2006
Posts: 80
02-01-2007 07:28
Hi again.

I wrote the following code to create x numbers by random. Also i control that there are no numbers twice.



CODE




do
{
@goTO;
integer random = llCeil(llFrand(45));
ZUFALLS_ZAHLEN = ZUFALLS_ZAHLEN + (string)random;

nr1 = llList2String(ZUFALLS_ZAHLEN,3);
nr2 = llList2String(ZUFALLS_ZAHLEN,4);
nr3 = llList2String(ZUFALLS_ZAHLEN,5);


if((string)random == nr1) hits++;
if((string)random == nr2) hits++;
if((string)random == nr3) hits++;




if(hits == 1)
{

anzRandoms++;
hits = 0;
// jump goTO;
}

if(hits>1)
{
ZUFALLS_ZAHLEN = llDeleteSubList(ZUFALLS_ZAHLEN, -1, -1);
llInstantMessage(quicktipper, "number already picked. picking new one....");
//anzRandoms--;
hits = 0;
jump goTO;
}



}while(anzRandoms < 3);





but it takes about 20s to choose those numbers. too long if u ask me.. do u know an algorithm that makes it faster? thx u all :)
Stephen Zenith
Registered User
Join date: 15 May 2006
Posts: 1,029
02-01-2007 07:57
Here's another way of doing it - it puts the numbers 1-49 into a list, together with a random number between 0 and 1,000,000. It then sorts the list on the random number, which has the effect of sorting 1-49 into a random order. So you can then pick the first 3 numbers from the list, knowing that they're random and non-identical.

It's really more of a shuffle than a random selection but it should work for you.

CODE

integer MAX_NUM = 49;
list numbers;

initList ()
{
integer i;
for (i = 0; i < MAX_NUM; i++)
{
numbers += llFrand (1000000);
numbers += i;
}
numbers = llListSort (numbers, 2, TRUE);
}

integer getNumber (integer pos)
{
return llList2Integer (numbers, 2 * pos + 1);
}



I'm not in world, so I can't test it, but the theory should be right.
_____________________
Daisy Rimbaud
Registered User
Join date: 12 Oct 2006
Posts: 764
02-01-2007 08:08
That's neat, I like it.
Edison Swain
Registered User
Join date: 7 Dec 2006
Posts: 51
02-01-2007 08:46
From: Stephen Zenith
Here's another way of doing it - it puts the numbers 1-49 into a list, together with a random number between 0 and 1,000,000. It then sorts the list on the random number, which has the effect of sorting 1-49 into a random order. So you can then pick the first 3 numbers from the list, knowing that they're random and non-identical.

It's really more of a shuffle than a random selection but it should work for you.

CODE

integer MAX_NUM = 49;
list numbers;

initList ()
{
integer i;
for (i = 0; i < MAX_NUM; i++)
{
numbers += llFrand (1000000);
numbers += i;
}
numbers = llListSort (numbers, 2, TRUE);
}

integer getNumber (integer pos)
{
return llList2Integer (numbers, 2 * pos + 1);
}



I'm not in world, so I can't test it, but the theory should be right.


You could create a list called "numbers" of just the numbers 1 - 49 and use something like this:

list randomPicks = llList2List(llListRandomize(numbers, 1), 0, 2)

This should return a new list comprised of the first 3 list items of a random sorting of "numbers", and should be sufficient. If you need more than 3, just change the last number in that line (the 2) to however many you need minus 1.
Stephen Zenith
Registered User
Join date: 15 May 2006
Posts: 1,029
02-01-2007 08:59
From: Edison Swain
You could create a list called "numbers" of just the numbers 1 - 49 and use something like this:

list randomPicks = llList2List(llListRandomize(numbers, 1), 0, 2)

This should return a new list comprised of the first 3 list items of a random sorting of "numbers", and should be sufficient. If you need more than 3, just change the last number in that line (the 2) to however many you need minus 1.


Heh, never knew there was a llListRandomize function! Nice job, with yours you can even populate the list statically, and if he needs the individual elements (rather than a list of 3 numbers) you can get rid of the llList2List call as well.
_____________________
Osgeld Barmy
Registered User
Join date: 22 Mar 2005
Posts: 3,336
02-01-2007 21:48
CODE

//random number picker

integer how_many_to_pick = 10;
integer number_cap = 100;

default
{
touch_start(integer total_number)
{
list numbers;
integer counter;
do
{
integer rnd_number = llRound(llFrand(number_cap));

if (llListFindList(numbers, [rnd_number] ) == -1)
{
numbers += rnd_number;
++counter;
}
}

while (counter != how_many_to_pick);

llSetText ("Your Random Numbers\n" + llDumpList2String(numbers,"\n"), <1,1,1>,1);
}
}


... back to the original question, altho i think a shuffle is a more effecient idea too

some example stats on a script defecient simulator (my workshop)
CODE


[23:02] Object: 256 numbers
[23:03] Object: completed in 67.034317 seconds

--> [23:05] Object: 100 numbers
--> [23:05] Object: completed in 19.296743 seconds

[23:07] Object: 50 numbers
[23:07] Object: completed in 10.978619 seconds

[23:08] Object: 25 numbers
[23:08] Object: completed in 2.759773 seconds

[23:09] Object: 10 numbers
[23:09] Object: completed in 1.096096 seconds

[23:10] Object: 5 numbers
[23:10] Object: completed in 0.402450 seconds
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
pseudo code
02-02-2007 08:51
This might not be faster...

CODE
Given a list [ 1 ...  n ], Choose 3 without replacement

for p = 1 to 3
Pick a random number q in [p,n]
Swap items at p and q

The first three are now "random" and equally probably.

You can replace 3 with any number up to n