Click to See Complete Forum and Search --> : Javascript memory?
charco
09-25-2006, 04:49 PM
Anyone know a code that allows javascript to remember which random numbers it has generated so as not to allow them in the future? Does such a thing exist? Is it possible?
What I have is a random generator:
Math.round(100*Math.random())
giving me integers from 0 to 100 .... how can I stop it giving me the same number later on?
Can I set a variable say var[i] equal to the random number and then check for it when the next random is selected?
sort of this in a check loop
function uniqueRandom(){
var i=0
n=Math.round(100*Math.random())
var[i]=n
i++
only with some kind of while check loop
(bit of a novice here, you understand)
Try this
var usedNumbers = new Array();
function uniqueRandom(n) {
var r = ~~(n*Math.random());
var len = usedNumbers.length;
for (var i=0; i<len; i++) {
if (usedNumbers[i] == r)
return uniqueRandom(n);
}
usedNumbers[len] = r;
return r;
}
It will call uniqueRandom recursively until a random number is generated which is not stored in the usedNumbers[] array. Note that I have not tested it....such a bad habit of mine :)
btw: Using the ~ operator twice is much faster than Math.round()
EDIT: Come to think of it you should not use the function for a large n. The running time of the function increases dramatically. You might implement the usedNumbers as a heap, but this is to much work on me right now. As the function is probalistic you might also want to add some kind of safety feature to prevent a stack overflow. This is easily done by addingvar usedNumbers = new Array();
var MAX_RUN = 6; // Maximum number of recursive calls
function uniqueRandom(n,max_run) {
// Safety precaution to avoid stack overflow
if (!max_run)
throw new Error('Max. number of recursive calls exceded.');
var len = usedNumbers.length;
// Check that n is actually > than used numbers
if (n <= len)
throw new Error('All numbers between 0 and ' + n + ' have been generated.');
var r = ~~(n*Math.random());
for (var i=0; i<len; i++) {
if (usedNumbers[i] == r)
return uniqueRandom(n,--max_run);
}
usedNumbers[len] = r;
return r;
}
// To get a new random number in [0,100]
try {
var newRandom = uniqueRandom(100,MAX_RUN);
}
catch(e) {
alert(e);
}
The above is not perfect either. Kind of interesting problem. Does anyone else have an idea?
Well this way is actually much easier
// Generate array with [0,n] integers
var max = 100;
var numbers = new Array(max+1);
for(var i=0; i<max+1; i++)
numbers[i] = i;
function uniqueRandom() {
var len = numbers.length;
var r = ~~(len*Math.random());
var tmp = numbers[r];
for(var i=r; i<len-1; i++)
numbers[i]++;
numbers.length--;
return tmp;
}
Now you start by generating 100 integers and each time you want a unique new integer, you pick it at random and remove that number from the array. As the numbers are ordered ascending, removing a number is the same as incrementing all the following numbers but the very last and decrementing the array length.
JMRKER
09-25-2006, 08:51 PM
Question for 'Dok':
Neat method for 100 integers, but how does this answer the question about saving the values between site visits. Would he not have to save the information in some sort of cookie? After 100 visits, would he start repeating the random number list? Would saving 100 numbers over-flow the cookie file size limit?
I don't mean to interfere with your answer to 'charco', just interested in case I wanted to use the method at some future time. I do think it has definite possiblities.
charco
09-26-2006, 12:53 AM
thanks for the replies folks, but ....Just one question.
What on earth is the ~ operator?
it doesn't appear in my Javascript book or web lists of operators such as: http://www.javascriptkit.com/jsref/operators.shtml or
http://www.w3schools.com/js/js_operators.asp
damn, I don't even know what its called!!
and the ~~ ? What is it doing?
charco
09-26-2006, 01:09 AM
Hang on, just found something..
It's called a bitwise NOT operator, let me get this straight..
it forces a number into its inverse in binary and loses the part after the decimal point?
Then repeating it again produces the original number as an integer.
Does it round the decimal part up or down or don't we know?
i.e. does ~2.673 = 10 or 11
Orc Scorcher
09-26-2006, 02:53 AM
If you're desperate for speed then X | 0 is faster than ~~X.
charco
09-26-2006, 03:32 AM
sorry, don't know what you mean.
What does X|0 mean? pipe zero? is this an operator
Orc Scorcher
09-26-2006, 03:43 AM
| is the bitwise OR operator. X | 0 rounds X down to the nearest integer (or rounds up, if X is negative).
charco
09-26-2006, 04:12 AM
ok - thanks
@ JMRKER
Yes you would have to use coockies (or server side scripting) in order to remember which numbers have been used across visits. I do not know whether charco meant for this.
@ Orc Scorcher
If you're desperate for speed then X | 0 is faster than ~~X.
Nice :cool:
charco
11-30-2006, 06:12 AM
Well this way is actually much easier
// Generate array with [0,n] integers
var max = 100;
var numbers = new Array(max+1);
for(var i=0; i<max+1; i++)
numbers[i] = i;
function uniqueRandom() {
var len = numbers.length;
var r = ~~(len*Math.random());
var tmp = numbers[r];
for(var i=r; i<len-1; i++)
numbers[i]++;
numbers.length--;
return tmp;
}
Now you start by generating 100 integers and each time you want a unique new integer, you pick it at random and remove that number from the array. As the numbers are ordered ascending, removing a number is the same as incrementing all the following numbers but the very last and decrementing the array length.
OK I've tried to incorporate this function into my program in several guises but I just can't get it to work. Any sympathetic soul out there like to lend a hand?
I have an array with (for example) quotes and I don't want the same quote repeated twice before all the quotes have been used up.
I have a simple form to allow me to set the number of quotes required and an external javascript. NO-matter what I do there are repeat quotations.
The script is:
//------initialise variables ------------
total=0
//set up array
//-------------------------------
quote=new Array();
quote[0] = new Array("A footballer ripped open his penis after being violently tackled during a match. Chavdar Yankow had to have six stitches after he sustained a three-inch gash playing for Hamburg 96 in Germany. Though his shorts were soaked with blood, the 21-year-old returned to the pitch after being patched up and his side went on to score a 2-0 win over Frankfurt. (SKY NEWS)");
quote[1] = new Array("He's pulling him off! The Spanish manager is pulling his captain off!(RTE's George Hamilton on Spain manager Luis Suarez's substitution of Butragueno during their world cup qualifier with Ireland in Seville,1992).");
quote[2] = new Array("Bill Frindal has done a bit of mental arithmetic with a calculator (John Arlott)");
quote[3] = new Array("I owe a lot to my parents, especially my mother and father (Greg Norman)");
quote[4] = new Array("Sure there have been injuries and deaths in boxing - but none of them serious (Alan Minter)");
quote[5] = new Array("The racecourse is as level as a billiard ball (John Francombe) ");
quote[6] = new Array("If history repeats itself, I should think we can expect the same thing again (Terry Venables)");
quote[7] = new Array("He dribbles a lot and the opposition don't like it - you can see it all over their faces. (Ron Atkinson)");
quote[8] = new Array("Ah, isn't that nice, the wife of the Cambridge president is kissing the cox of the Oxford crew. (Harry Carpenter - BBC TV Boat Race 1977)");
quote[9] = new Array("Julian Dicks is everywhere. It's like they've got eleven Dicks on the field. (Metro Radio)");
//--------------------------------------------
function setUp(){
numq=document.forms[0].numq.value
numbers=new Array();
for(var i=0; i<numq; i++){
numbers[i]=i;
}
}
//-------------------------------------------------------------------
function begin(){
uniqueRandom()
//check to see if the total quotes has reached target (numq) and increment if not --
if (total<numq){
total++
//------set the quote out on the screen----------------------------
var quoteHTML=''
quoteHTML+=quote[m]
document.getElementById('quotearea').innerHTML=quoteHTML
document.forms[0].qNumber.value=m
document.forms[0].qDone.value=total
}
else {
freeze();
}
}
//------------------------------------------
function uniqueRandom() {
var len=numbers.length;
var r=Math.round(len*Math.random());
m=numbers[r];
for(var i=r; i<len-1; i++){
numbers[i]++;
}
numbers.length--;
}
//-------------------------------------------------------
function doFunctions(){
RefreshForm()
SetFocus()
}
function clearAll(){
document.frm.qNumber.value=0
document.frm.qDone.value=0
var displayHTML=''
document.getElementById('quotearea').innerHTML=displayHTML
total=0
}
function freeze(){
endHTML=''
endHTML+='I\'m sorry that\'s all the quotes there are! '
document.getElementById('quotearea').innerHTML=endHTML
}
//----------------------- end ---------------------------------------
any help cheerfully received....