Re: [Flashcoders] Producing a random list with no repeats
If that happens, it's a bug in the player. From the docs: "Returns a pseudo-random number n, where 0 <= n < 1. " So, the biggest number random returns can approximate 1, but should never be 1. What I got wrong in my original answer was that multiplying by 2 and then rounding introduces a bias towards 1 (and then if you substract 1, the bias is towards 0). Think about it this way: You've got a number between 0 and 1.9 when you do Math.random * 2. That is, a number that can get very close to 2, but never be actually 2. If you round it you'll get: 0 for 0...0.49 1 for 0.5...1.49 2 for 1.5...19 The actual numbers might not be exact as I'm not sure what's the boundary for rounding up or down; I'm also considering only two decimals for simplicity. But anyway, the distribution is obviously not even. There's about a 0.25 chance of getting 0, the same chance of getting 2, but the double, 0.5, of getting 1. However, if you multiply by 3 and floor the result (or coerce it to int for that matter), you get rid of the bias: Math.random * 3 will give a number in the range 0...2.99 So, if you get rid of the decimal part, you have: 0 for 0...0.99 1 for 1...1.99 2 for 2...2.99 Which gives a result that's clearly more evenly distributed than the first approach. 2010/5/9 Steven Sacks > In the exception that Math.random() returns 1, in which case you would get > 2. > > I don't use Math.random(), though, I use the Parker-Miller PRNG. > > > > > On 5/9/2010 5:01 PM, Juan Pablo Califano wrote: > >> PS 2: I think the correct way to write the function that returns a number >> in >> the range -1 / 1 is: >> >> Math.floor(Math.random * 3) - 1 >> >> In this case, you could indeed use int() instead of a static Math method, >> so >> I guess I was wrong about your function needing a Math.round call. >> > ___ > Flashcoders mailing list > Flashcoders@chattyfig.figleaf.com > http://chattyfig.figleaf.com/mailman/listinfo/flashcoders > ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
Re: [Flashcoders] Producing a random list with no repeats
In the exception that Math.random() returns 1, in which case you would get 2. I don't use Math.random(), though, I use the Parker-Miller PRNG. On 5/9/2010 5:01 PM, Juan Pablo Califano wrote: PS 2: I think the correct way to write the function that returns a number in the range -1 / 1 is: Math.floor(Math.random * 3) - 1 In this case, you could indeed use int() instead of a static Math method, so I guess I was wrong about your function needing a Math.round call. ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
Re: [Flashcoders] Producing a random list with no repeats
PS 2: I think the correct way to write the function that returns a number in the range -1 / 1 is: Math.floor(Math.random * 3) - 1 In this case, you could indeed use int() instead of a static Math method, so I guess I was wrong about your function needing a Math.round call. 2010/5/9 Juan Pablo Califano > Steven, sorry to contradict you, but although your code is simple and sort > of works, there a couple of problems with it. > > First, the sorting function is wrong. A sorting function is supposed to > return -1,0 or 1. But it only returns -1 or 0. > > The problem is you are coercing the result to int. You should use > Math.round instead. > > int(Math.random() * 2) will return 1 or 0, never 2, because the biggest > value Math.random will return will be close to 1, but never will be 1. So, > if Math.random returns say, 0.9, after you multiply you get 1.8; since > you're using int(), decimals will just be discarded (instead of rounded) and > the result will be 1. There's no way you'll get 2, only 1 or 0. Then you > substract 1, so your sorting function will return either -1 or 0. > > Second, you don't need to sort the whole list. It's much more work than > it's needed to shuffle the array. While the Fisher-Yates algorithm is > linear, the sort is not. That is, if you have 40 items, you know the > Fisher-Yates will "visit" each list slot only once. That's not the case with > the sort method. It grows exponentially. Well, maybe not exactly > exponential, I'm not possitive, but it's not linear anyway, as this code > shows: > > var list:Array = []; > var numItems:int = 40; > for(var i:int = 0; i < numItems; i++) { > list[i] = i; > } > > var calls:int = 0; > function randomize(a:int, b:int):int > { > calls++; > return int(Math.random() * 2) - 1; > } > > list.sort(randomize); > trace("calls:" + calls); > > Change numItems and you'll see what I mean. Bottom line, you're doing more > work than you need: you're calling a function instead of doing your > comparison inline and you are calling Math.random more than it's actually > needed to sort the list. > > Third, the sorting algorithm works under the assumption that given two > objects they allways sort the same: either the first one is less than, equal > or greater than the second. That doesn't hold true if your sorting function > returns a random result. And I think maybe that's why the number of calls > that the above code prints vary even when you have the same number of items. > > Cheers > Juan Pablo Califano > > PS. I also used the method you describe (for years) until I read about its > problems, so I thought maybe this is a good opportunity to pass this info > on. To be honest, though, I don't think it will be a problem > preformance-wise unless you have a rather big array. > > 2010/5/9 Steven Sacks > > Here's a very clean, fast and simple way to randomize an array. >> >> array.sort(randomizeFunction); >> >> function randomize(a:int, b:int):int >> { >>return int(Math.random() * 2) - 1; >> } >> >> If you're not happy with Math.random()'s randomness, there are plenty of >> other random number generators out there, such as: >> >> >> http://lab.polygonal.de/2007/04/21/a-good-pseudo-random-number-generator-prng/ >> >> And Grant Skinner's Rndm: >> http://www.gskinner.com/blog/archives/2008/01/source_code_see.html >> >> ___ >> Flashcoders mailing list >> Flashcoders@chattyfig.figleaf.com >> http://chattyfig.figleaf.com/mailman/listinfo/flashcoders >> > > ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
Re: [Flashcoders] Producing a random list with no repeats
You're right. I was careless on two counts. Fisher-Yates it is. On 5/9/2010 4:36 PM, Juan Pablo Califano wrote: Steven, sorry to contradict you, but although your code is simple and sort of works, there a couple of problems with it. First, the sorting function is wrong. A sorting function is supposed to return -1,0 or 1. But it only returns -1 or 0. The problem is you are coercing the result to int. You should use Math.round instead. int(Math.random() * 2) will return 1 or 0, never 2, because the biggest value Math.random will return will be close to 1, but never will be 1. So, if Math.random returns say, 0.9, after you multiply you get 1.8; since you're using int(), decimals will just be discarded (instead of rounded) and the result will be 1. There's no way you'll get 2, only 1 or 0. Then you substract 1, so your sorting function will return either -1 or 0. Second, you don't need to sort the whole list. It's much more work than it's needed to shuffle the array. While the Fisher-Yates algorithm is linear, the sort is not. That is, if you have 40 items, you know the Fisher-Yates will "visit" each list slot only once. That's not the case with the sort method. It grows exponentially. Well, maybe not exactly exponential, I'm not possitive, but it's not linear anyway, as this code shows: var list:Array = []; var numItems:int = 40; for(var i:int = 0; i< numItems; i++) { list[i] = i; } var calls:int = 0; function randomize(a:int, b:int):int { calls++; return int(Math.random() * 2) - 1; } list.sort(randomize); trace("calls:" + calls); Change numItems and you'll see what I mean. Bottom line, you're doing more work than you need: you're calling a function instead of doing your comparison inline and you are calling Math.random more than it's actually needed to sort the list. Third, the sorting algorithm works under the assumption that given two objects they allways sort the same: either the first one is less than, equal or greater than the second. That doesn't hold true if your sorting function returns a random result. And I think maybe that's why the number of calls that the above code prints vary even when you have the same number of items. Cheers Juan Pablo Califano PS. I also used the method you describe (for years) until I read about its problems, so I thought maybe this is a good opportunity to pass this info on. To be honest, though, I don't think it will be a problem preformance-wise unless you have a rather big array. 2010/5/9 Steven Sacks Here's a very clean, fast and simple way to randomize an array. array.sort(randomizeFunction); function randomize(a:int, b:int):int { return int(Math.random() * 2) - 1; } If you're not happy with Math.random()'s randomness, there are plenty of other random number generators out there, such as: http://lab.polygonal.de/2007/04/21/a-good-pseudo-random-number-generator-prng/ And Grant Skinner's Rndm: http://www.gskinner.com/blog/archives/2008/01/source_code_see.html ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
Re: [Flashcoders] Producing a random list with no repeats
Steven, sorry to contradict you, but although your code is simple and sort of works, there a couple of problems with it. First, the sorting function is wrong. A sorting function is supposed to return -1,0 or 1. But it only returns -1 or 0. The problem is you are coercing the result to int. You should use Math.round instead. int(Math.random() * 2) will return 1 or 0, never 2, because the biggest value Math.random will return will be close to 1, but never will be 1. So, if Math.random returns say, 0.9, after you multiply you get 1.8; since you're using int(), decimals will just be discarded (instead of rounded) and the result will be 1. There's no way you'll get 2, only 1 or 0. Then you substract 1, so your sorting function will return either -1 or 0. Second, you don't need to sort the whole list. It's much more work than it's needed to shuffle the array. While the Fisher-Yates algorithm is linear, the sort is not. That is, if you have 40 items, you know the Fisher-Yates will "visit" each list slot only once. That's not the case with the sort method. It grows exponentially. Well, maybe not exactly exponential, I'm not possitive, but it's not linear anyway, as this code shows: var list:Array = []; var numItems:int = 40; for(var i:int = 0; i < numItems; i++) { list[i] = i; } var calls:int = 0; function randomize(a:int, b:int):int { calls++; return int(Math.random() * 2) - 1; } list.sort(randomize); trace("calls:" + calls); Change numItems and you'll see what I mean. Bottom line, you're doing more work than you need: you're calling a function instead of doing your comparison inline and you are calling Math.random more than it's actually needed to sort the list. Third, the sorting algorithm works under the assumption that given two objects they allways sort the same: either the first one is less than, equal or greater than the second. That doesn't hold true if your sorting function returns a random result. And I think maybe that's why the number of calls that the above code prints vary even when you have the same number of items. Cheers Juan Pablo Califano PS. I also used the method you describe (for years) until I read about its problems, so I thought maybe this is a good opportunity to pass this info on. To be honest, though, I don't think it will be a problem preformance-wise unless you have a rather big array. 2010/5/9 Steven Sacks > Here's a very clean, fast and simple way to randomize an array. > > array.sort(randomizeFunction); > > function randomize(a:int, b:int):int > { >return int(Math.random() * 2) - 1; > } > > If you're not happy with Math.random()'s randomness, there are plenty of > other random number generators out there, such as: > > > http://lab.polygonal.de/2007/04/21/a-good-pseudo-random-number-generator-prng/ > > And Grant Skinner's Rndm: > http://www.gskinner.com/blog/archives/2008/01/source_code_see.html > > ___ > Flashcoders mailing list > Flashcoders@chattyfig.figleaf.com > http://chattyfig.figleaf.com/mailman/listinfo/flashcoders > ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
Re: [Flashcoders] Producing a random list with no repeats
Here's a very clean, fast and simple way to randomize an array. array.sort(randomizeFunction); function randomize(a:int, b:int):int { return int(Math.random() * 2) - 1; } If you're not happy with Math.random()'s randomness, there are plenty of other random number generators out there, such as: http://lab.polygonal.de/2007/04/21/a-good-pseudo-random-number-generator-prng/ And Grant Skinner's Rndm: http://www.gskinner.com/blog/archives/2008/01/source_code_see.html ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
Re: [Flashcoders] Producing a random list with no repeats
ah my bad , i think this is probably the same as fisher yates;) On Fri, May 7, 2010 at 12:20 PM, Hans Wichman < j.c.wich...@objectpainters.com> wrote: > Hi, > > here an alternative way of producing a random array: > > /** > * Randomizes a copy of this array. > */ > public function randomize (pArray:Array):Array { > var newArray:Array = pArray.slice(); > > var i:Number = newArray.length; > while (i) { > var p:Number = random(i); > var t:Object = newArray[--i]; > newArray[i] = newArray[p]; > newArray[p] = t; > } > > return newArray; > } > regards > JC > On Thu, May 6, 2010 at 3:27 AM, Juan Pablo Califano < > califa010.flashcod...@gmail.com> wrote: > >> A simple way: >> >> Put all the candidate numbers in a list (in this case, 1 to 40). Then pick >> randomly from that array, one at the time, and make sure you remove that >> number from the candidates list, so you can't have duplicates. >> >> In code (untested): >> >> function getRandomList():Array { >>var min:Number = 1; >>var max:Number = 40; >>var numItems:Number = 10; >>var candidates:Array = []; >>// fill up the candidates list with the "eligible" numbers >>for(var i:Number = min; i <= max; i++) { >>candidates.push(i); >>} >> >>var list:Array = []; >>var idx:Number = 0; >>var selectedNumber:Number = 0; >>for(i = 0; i < numItems; i++) { >>// get a number from the candidates list, randomly. Add it to the >> result and remove it from the candidates list (using splice) >>idx = Math.floor(Math.random() * candidates.length); >>selectedNumber = candidates.splice(idx,1)[0]; >>list.push(selectedNumber); >>} >>return list; >> } >> >> >> Cheers >> Juan Pablo Califano >> >> 2010/5/5 Alan Neilsen >> >> > I am working in ActionScript 2. I want to create a quiz in which 10 >> > questions are randomly selected from a block of 40 questions. I found >> the >> > following code, but I can't work out how to stop it doubling up the >> > questions. >> > >> > function randRange(min:Number, max:Number):Number { >> >var randomNum:Number = Math.floor(Math.random() * (max - min + 1)) + >> > min; >> >return randomNum; >> > } >> > for (var i = 0; i < 10; i++) { >> >var n:Number = randRange(1, 40) >> >trace(n); >> > } >> > >> > When I run this it outputs a list of numbers like 40 13 17 12 27 12 >> 3 >> > 17 9 15 which means some questions (in this case 17 and 12) will >> appear >> > twice in my quiz. >> > Bearing in mind that I am a bit of an ActionScript dummy, can anybody >> > suggest a way to modify the above script to prevent the same number >> being >> > generated more than once. >> > >> > This message is for the named person’s use only. It may contain >> > confidential, proprietary or legally privileged information. No >> > confidentiality or privilege is waived or; lost by any mistransmission. >> If >> > you receive this message in error, please immediately delete it and all >> > copies of it from your system, destroy any hard copies of it and notify >> > the sender. You must not directly or indirectly, use, disclose, >> > distribute, print or copy any part of this message if you are not the >> > intended recipient. GOULBURN OVENS INSTITUTE OF TAFE and >> > any of its subsidiaries each reserve the right to monitor all e-mail >> > communications through its networks. Any views expressed in this >> > message are those of the individual sender, except where the >> > message states otherwise and the sender is authorised to state them >> > to be the views of any such entity. >> > >> > >> > >> # >> > This e-mail message has been scanned for Viruses and Content and cleared >> > by MailMarshal >> > >> > >> # >> > ___ >> > Flashcoders mailing list >> > Flashcoders@chattyfig.figleaf.com >> > http://chattyfig.figleaf.com/mailman/listinfo/flashcoders >> > >> ___ >> Flashcoders mailing list >> Flashcoders@chattyfig.figleaf.com >> http://chattyfig.figleaf.com/mailman/listinfo/flashcoders >> > > ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
Re: [Flashcoders] Producing a random list with no repeats
Hi, here an alternative way of producing a random array: /** * Randomizes a copy of this array. */ public function randomize (pArray:Array):Array { var newArray:Array = pArray.slice(); var i:Number = newArray.length; while (i) { var p:Number = random(i); var t:Object = newArray[--i]; newArray[i] = newArray[p]; newArray[p] = t; } return newArray; } regards JC On Thu, May 6, 2010 at 3:27 AM, Juan Pablo Califano < califa010.flashcod...@gmail.com> wrote: > A simple way: > > Put all the candidate numbers in a list (in this case, 1 to 40). Then pick > randomly from that array, one at the time, and make sure you remove that > number from the candidates list, so you can't have duplicates. > > In code (untested): > > function getRandomList():Array { >var min:Number = 1; >var max:Number = 40; >var numItems:Number = 10; >var candidates:Array = []; >// fill up the candidates list with the "eligible" numbers >for(var i:Number = min; i <= max; i++) { >candidates.push(i); >} > >var list:Array = []; >var idx:Number = 0; >var selectedNumber:Number = 0; >for(i = 0; i < numItems; i++) { >// get a number from the candidates list, randomly. Add it to the > result and remove it from the candidates list (using splice) >idx = Math.floor(Math.random() * candidates.length); >selectedNumber = candidates.splice(idx,1)[0]; >list.push(selectedNumber); >} >return list; > } > > > Cheers > Juan Pablo Califano > > 2010/5/5 Alan Neilsen > > > I am working in ActionScript 2. I want to create a quiz in which 10 > > questions are randomly selected from a block of 40 questions. I found the > > following code, but I can't work out how to stop it doubling up the > > questions. > > > > function randRange(min:Number, max:Number):Number { > >var randomNum:Number = Math.floor(Math.random() * (max - min + 1)) + > > min; > >return randomNum; > > } > > for (var i = 0; i < 10; i++) { > >var n:Number = randRange(1, 40) > >trace(n); > > } > > > > When I run this it outputs a list of numbers like 40 13 17 12 27 12 > 3 > > 17 9 15 which means some questions (in this case 17 and 12) will > appear > > twice in my quiz. > > Bearing in mind that I am a bit of an ActionScript dummy, can anybody > > suggest a way to modify the above script to prevent the same number being > > generated more than once. > > > > This message is for the named person’s use only. It may contain > > confidential, proprietary or legally privileged information. No > > confidentiality or privilege is waived or; lost by any mistransmission. > If > > you receive this message in error, please immediately delete it and all > > copies of it from your system, destroy any hard copies of it and notify > > the sender. You must not directly or indirectly, use, disclose, > > distribute, print or copy any part of this message if you are not the > > intended recipient. GOULBURN OVENS INSTITUTE OF TAFE and > > any of its subsidiaries each reserve the right to monitor all e-mail > > communications through its networks. Any views expressed in this > > message are those of the individual sender, except where the > > message states otherwise and the sender is authorised to state them > > to be the views of any such entity. > > > > > > > # > > This e-mail message has been scanned for Viruses and Content and cleared > > by MailMarshal > > > > > # > > ___ > > Flashcoders mailing list > > Flashcoders@chattyfig.figleaf.com > > http://chattyfig.figleaf.com/mailman/listinfo/flashcoders > > > ___ > Flashcoders mailing list > Flashcoders@chattyfig.figleaf.com > http://chattyfig.figleaf.com/mailman/listinfo/flashcoders > ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
RE: [Flashcoders] Producing a random list with no repeats
/** * Generates an array of random numbers from 1 or 0 to max where all numbers through max are used, and no number is zero (if specified). * Specify true if no zeros are to be included, specify false if zeros are to be included in the resulting array. * @param max the maximum range for the numbers. * @param useZero Specify true if no zeros are to be included, specify false if zeros are to be included in the resulting array. * @return an array of random numbers where no number is the same. * */ public static function rndNumArray(max:int, useZero:Boolean=false):Array { var array:Array = []; for (var i1:int = 0; i1 < max; i1++) { array.push(""); } var i2:int = 0; while (i2 < array.length) { var rndNum:Number = rndNum(0, max); if (!containedInArray(rndNum, array) ) { //if (useZero) rndNum = rndNum-1; array[i2] = rndNum; i2++; } } if (useZero) { var arrLen:int = array.length; for (var i3:int = 0; i3 < arrLen; i3++) { array[i3] = array[i3]-1; } } return array; } /** * Generates a random number within the given range. * * @example * var myRandomNumber:Number = rndNum(2, 13); * trace(myRandomNumber); //returns 7 (a random between 2 and 13) * * @param minVal the minimum number for the range. * @param maxVal the maxiumum number for the range. * @return returns the random number generated. * * */ public static function rndNum(minVal:Number, maxVal:Number):Number { return minVal + Math.floor(Math.random()*(maxVal+1-minVal)); } Jason Merrill Bank of America Global Learning Learning & Performance Solutions Join the Bank of America Flash Platform Community and visit our Instructional Technology Design Blog (note: these are for Bank of America employees only) -Original Message- From: flashcoders-boun...@chattyfig.figleaf.com [mailto:flashcoders-boun...@chattyfig.figleaf.com] On Behalf Of kennethkawam...@gmail.com Sent: Thursday, May 06, 2010 5:03 AM To: Flash Coders List Subject: Re: [Flashcoders] Producing a random list with no repeats I always use Fisher-Yates shuffle method to randomise an Array, which yields more unbiased result. http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle My AS3 interpretation of Fisher-Yates is as follows; I can just call this from anywhere in my scripts ;) package utils { public function fisherYates(arr:Array):void { var i:uint = arr.length; while(--i){ var j:uint = Math.floor(Math.random()*(i + 1)); var tmpI:Object = arr[i]; var tmpJ:Object = arr[j]; arr[i] = tmpJ; arr[j] = tmpI; } } } -- Kenneth Kawamoto http://www.materiaprima.co.uk/ On 6 May 2010 02:27, Juan Pablo Califano wrote: > A simple way: > > Put all the candidate numbers in a list (in this case, 1 to 40). Then > pick randomly from that array, one at the time, and make sure you > remove that number from the candidates list, so you can't have duplicates. > > In code (untested): > > function getRandomList():Array { > var min:Number = 1; > var max:Number = 40; > var numItems:Number = 10; > var candidates:Array = []; > // fill up the candidates list with the "eligible" numbers > for(var i:Number = min; i <= max; i++) { > candidates.push(i); > } > > var list:Array = []; > var idx:Number = 0; > var selectedNumber:Number = 0; > for(i = 0; i < numItems; i++) { > // get a number from the candidates list, randomly. Add it to > the result and remove it from the candidates list (using splice) > idx = Math.floor(Math.random() * candidates.leng
Re: [Flashcoders] Producing a random list with no repeats
I always use Fisher-Yates shuffle method to randomise an Array, which yields more unbiased result. http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle My AS3 interpretation of Fisher-Yates is as follows; I can just call this from anywhere in my scripts ;) package utils { public function fisherYates(arr:Array):void { var i:uint = arr.length; while(--i){ var j:uint = Math.floor(Math.random()*(i + 1)); var tmpI:Object = arr[i]; var tmpJ:Object = arr[j]; arr[i] = tmpJ; arr[j] = tmpI; } } } -- Kenneth Kawamoto http://www.materiaprima.co.uk/ On 6 May 2010 02:27, Juan Pablo Califano wrote: > A simple way: > > Put all the candidate numbers in a list (in this case, 1 to 40). Then pick > randomly from that array, one at the time, and make sure you remove that > number from the candidates list, so you can't have duplicates. > > In code (untested): > > function getRandomList():Array { > var min:Number = 1; > var max:Number = 40; > var numItems:Number = 10; > var candidates:Array = []; > // fill up the candidates list with the "eligible" numbers > for(var i:Number = min; i <= max; i++) { > candidates.push(i); > } > > var list:Array = []; > var idx:Number = 0; > var selectedNumber:Number = 0; > for(i = 0; i < numItems; i++) { > // get a number from the candidates list, randomly. Add it to the > result and remove it from the candidates list (using splice) > idx = Math.floor(Math.random() * candidates.length); > selectedNumber = candidates.splice(idx,1)[0]; > list.push(selectedNumber); > } > return list; > } > > > Cheers > Juan Pablo Califano > > 2010/5/5 Alan Neilsen > >> I am working in ActionScript 2. I want to create a quiz in which 10 >> questions are randomly selected from a block of 40 questions. I found the >> following code, but I can't work out how to stop it doubling up the >> questions. >> >> function randRange(min:Number, max:Number):Number { >> var randomNum:Number = Math.floor(Math.random() * (max - min + 1)) + >> min; >> return randomNum; >> } >> for (var i = 0; i < 10; i++) { >> var n:Number = randRange(1, 40) >> trace(n); >> } >> >> When I run this it outputs a list of numbers like 40 13 17 12 27 12 3 >> 17 9 15 which means some questions (in this case 17 and 12) will appear >> twice in my quiz. >> Bearing in mind that I am a bit of an ActionScript dummy, can anybody >> suggest a way to modify the above script to prevent the same number being >> generated more than once. ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
Re: [Flashcoders] Producing a random list with no repeats
A simple way: Put all the candidate numbers in a list (in this case, 1 to 40). Then pick randomly from that array, one at the time, and make sure you remove that number from the candidates list, so you can't have duplicates. In code (untested): function getRandomList():Array { var min:Number = 1; var max:Number = 40; var numItems:Number = 10; var candidates:Array = []; // fill up the candidates list with the "eligible" numbers for(var i:Number = min; i <= max; i++) { candidates.push(i); } var list:Array = []; var idx:Number = 0; var selectedNumber:Number = 0; for(i = 0; i < numItems; i++) { // get a number from the candidates list, randomly. Add it to the result and remove it from the candidates list (using splice) idx = Math.floor(Math.random() * candidates.length); selectedNumber = candidates.splice(idx,1)[0]; list.push(selectedNumber); } return list; } Cheers Juan Pablo Califano 2010/5/5 Alan Neilsen > I am working in ActionScript 2. I want to create a quiz in which 10 > questions are randomly selected from a block of 40 questions. I found the > following code, but I can't work out how to stop it doubling up the > questions. > > function randRange(min:Number, max:Number):Number { >var randomNum:Number = Math.floor(Math.random() * (max - min + 1)) + > min; >return randomNum; > } > for (var i = 0; i < 10; i++) { >var n:Number = randRange(1, 40) >trace(n); > } > > When I run this it outputs a list of numbers like 40 13 17 12 27 12 3 > 17 9 15 which means some questions (in this case 17 and 12) will appear > twice in my quiz. > Bearing in mind that I am a bit of an ActionScript dummy, can anybody > suggest a way to modify the above script to prevent the same number being > generated more than once. > > This message is for the named person’s use only. It may contain > confidential, proprietary or legally privileged information. No > confidentiality or privilege is waived or; lost by any mistransmission. If > you receive this message in error, please immediately delete it and all > copies of it from your system, destroy any hard copies of it and notify > the sender. You must not directly or indirectly, use, disclose, > distribute, print or copy any part of this message if you are not the > intended recipient. GOULBURN OVENS INSTITUTE OF TAFE and > any of its subsidiaries each reserve the right to monitor all e-mail > communications through its networks. Any views expressed in this > message are those of the individual sender, except where the > message states otherwise and the sender is authorised to state them > to be the views of any such entity. > > > # > This e-mail message has been scanned for Viruses and Content and cleared > by MailMarshal > > # > ___ > Flashcoders mailing list > Flashcoders@chattyfig.figleaf.com > http://chattyfig.figleaf.com/mailman/listinfo/flashcoders > ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
Re: [Flashcoders] Producing a random list with no repeats
Hi Allen, Just a thought, but maybe have the quiz numbers set in an array that the var n:Number is retrieved and have the min and max that the random code calls match the amount of items in the array. After selecting a question, remove it from the array, thus the array length (max) reduces and the random code still works, but the previous questions are no longer in the array to choose from. var numArray:Array = new Array(); numArray = [40, 20, 35, 4, 5, 9]; var currentNum:Number = null; function randRange(min:Number, max:Number):Number { var randomNum:Number = Math.floor(Math.random(max, min)); return randomNum; } for (var i = 0; i < numArray.length; i++) { var n:Number = randRange(0, numArray.length); currentNum = numArray[n]; numArray = numArray.splice(n); trace("incrament number: "+i); trace("currentNum: "+currentNum); trace("numArray: "+numArray); } This was off the top of the head, so you will need to test it. HTH, Karl On May 5, 2010, at 7:45 PM, Alan Neilsen wrote: I am working in ActionScript 2. I want to create a quiz in which 10 questions are randomly selected from a block of 40 questions. I found the following code, but I can't work out how to stop it doubling up the questions. function randRange(min:Number, max:Number):Number { var randomNum:Number = Math.floor(Math.random() * (max - min + 1)) + min; return randomNum; } for (var i = 0; i < 10; i++) { var n:Number = randRange(1, 40) trace(n); } When I run this it outputs a list of numbers like 40 13 17 12 27 12 3 17 9 15 which means some questions (in this case 17 and 12) will appear twice in my quiz. Bearing in mind that I am a bit of an ActionScript dummy, can anybody suggest a way to modify the above script to prevent the same number being generated more than once. This message is for the named persons use only. It may contain confidential, proprietary or legally privileged information. No confidentiality or privilege is waived or; lost by any mistransmission. If you receive this message in error, please immediately delete it and all copies of it from your system, destroy any hard copies of it and notify the sender. You must not directly or indirectly, use, disclose, distribute, print or copy any part of this message if you are not the intended recipient. GOULBURN OVENS INSTITUTE OF TAFE and any of its subsidiaries each reserve the right to monitor all e-mail communications through its networks. Any views expressed in this message are those of the individual sender, except where the message states otherwise and the sender is authorised to state them to be the views of any such entity. ## ### This e-mail message has been scanned for Viruses and Content and cleared by MailMarshal ## ### ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders Karl DeSaulniers Design Drumm http://designdrumm.com ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
Re: [Flashcoders] Producing a random list with no repeats
It's probably best just to create an Array or Vector containing numbers 1 to 40. (Vectors are only available in AS3, not sure about Array). Shuffle the array, then choose the first 10 elements. A reasonably effective way to shuffle an array is to step through the array, and for each element swap it with some other randomly selected element. Another approach is to start with an array whose elements contain numbers 1 through 40. Randomly select one of the 40 elements, record its value, and remove it from the array. Now you have 39 elements. Randomly select one of the 39 elements, record its value, and remove it from the array. Continue in this fashion until you've selected 10 elements. The worst approach is to repeatedly generate random numbers in the range 1 through 40, and add the number your list of questions only if it's not already on the list. The reason this approach is bad is that the execution time is unpredictable - you could be 'rolling the dice' hundreds of times and always getting numbers that are already on your list. On 2010-05-06 , at 08:45 , Alan Neilsen wrote: > I am working in ActionScript 2. I want to create a quiz in which 10 questions > are randomly selected from a block of 40 questions. I found the following > code, but I can't work out how to stop it doubling up the questions. ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
[Flashcoders] Producing a random list with no repeats
I am working in ActionScript 2. I want to create a quiz in which 10 questions are randomly selected from a block of 40 questions. I found the following code, but I can't work out how to stop it doubling up the questions. function randRange(min:Number, max:Number):Number { var randomNum:Number = Math.floor(Math.random() * (max - min + 1)) + min; return randomNum; } for (var i = 0; i < 10; i++) { var n:Number = randRange(1, 40) trace(n); } When I run this it outputs a list of numbers like 40 13 17 12 27 12 3 17 9 15 which means some questions (in this case 17 and 12) will appear twice in my quiz. Bearing in mind that I am a bit of an ActionScript dummy, can anybody suggest a way to modify the above script to prevent the same number being generated more than once. This message is for the named persons use only. It may contain confidential, proprietary or legally privileged information. No confidentiality or privilege is waived or; lost by any mistransmission. If you receive this message in error, please immediately delete it and all copies of it from your system, destroy any hard copies of it and notify the sender. You must not directly or indirectly, use, disclose, distribute, print or copy any part of this message if you are not the intended recipient. GOULBURN OVENS INSTITUTE OF TAFE and any of its subsidiaries each reserve the right to monitor all e-mail communications through its networks. Any views expressed in this message are those of the individual sender, except where the message states otherwise and the sender is authorised to state them to be the views of any such entity. # This e-mail message has been scanned for Viruses and Content and cleared by MailMarshal # ___ Flashcoders mailing list Flashcoders@chattyfig.figleaf.com http://chattyfig.figleaf.com/mailman/listinfo/flashcoders