For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > July 2004 > [SOLUTION] how can i generate 10 unique (non repeating) numbers









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author [SOLUTION] how can i generate 10 unique (non repeating) numbers
Absolut Newbie

2004-07-28, 8:56 pm

greets to Peter Scott for pointing to Randal Schwartz's answer on C.L.P.M.

http://groups.google.com/groups?hl=....stonehenge.com

[SOLUTION]
use List::Util from CPAN
http://search.cpan.org/~gbarr/Scala...ib/List/Util.pm

basically you use the module to create a group of numbers (like a card deck)
and then "deal" them randomly into an array.

use List::Util qw(shuffle);
@cards = shuffle 0..51; # 0..51 in a random order

so my final code looks like :
use List::Util qw(shuffle);
@shuffled = shuffle(1..10);
print "\@shuffled is --------> @shuffled\n";
@sorted = sort { $a <=> $b } @shuffled;
print "\@shuffled is now --------> @sorted\n";

[ORIGINAL QUESTION]
Hi,

I want to generate 10 numbers from 1..15 and put them in an array.

easy ?
while ($fill < 10){
$foo = int(rand(15));
unshift(@array, $foo);
$fill++;
}
print "the \@array is --> @array\n";

my problem is that many times the numbers repeat themselves in the array.

how can i generate 10 unique (non repeating) numbers from a range to put in
the array ?

thanx.



---

Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.725 / Virus Database: 480 - Release Date: 7/19/2004


Zeus Odin

2004-07-28, 8:56 pm

If you want to do it without the use of a module, you could

(1) add the 15 numbers to an array (the deck)
(2) choose a random number from the deck
(3) remove that random element and add it to another array (your hand)
(4) repeat until done (your hand has 10 numbers)

This sounds exactly like the solution below sans module:

#!/usr/bin/perl
use warnings;
use strict;

my @nums = 1 .. 15;
my @ten;

for (1 .. 10) {
push @ten, splice @nums, int(rand @nums), 1;
}
print "@ten";


"Absolut Newbie" <dotted_i@vitaemail.com> wrote in message
news:20040725141112.77136.qmail@onion.perl.org...
> greets to Peter Scott for pointing to Randal Schwartz's answer on C.L.P.M.
>
>

http://groups.google.com/groups?hl=....stonehenge.com
>
> [SOLUTION]
> use List::Util from CPAN
> http://search.cpan.org/~gbarr/Scala...ib/List/Util.pm
>
> basically you use the module to create a group of numbers (like a card

deck)
> and then "deal" them randomly into an array.



Guruguhan \ N

2004-07-28, 8:56 pm

Hi Zeus,
Your code and explanation are good. Incase I want 10 non =
repeated random numbers between 0 and 1 what needs to be done?=20

Regards
guruguhan

-----Original Message-----
From: Zeus Odin [mailto:zeus.odin@verizon.net]
Sent: Tuesday, July 27, 2004 5:17 AM
To: beginners@perl.org
Subject: Re: [SOLUTION] how can i generate 10 unique (non repeating)
numbers


If you want to do it without the use of a module, you could

(1) add the 15 numbers to an array (the deck)
(2) choose a random number from the deck
(3) remove that random element and add it to another array (your hand)
(4) repeat until done (your hand has 10 numbers)

This sounds exactly like the solution below sans module:

#!/usr/bin/perl
use warnings;
use strict;

my @nums =3D 1 .. 15;
my @ten;

for (1 .. 10) {
push @ten, splice @nums, int(rand @nums), 1;
}
print "@ten";


"Absolut Newbie" <dotted_i@vitaemail.com> wrote in message
news:20040725141112.77136.qmail@onion.perl.org...
> greets to Peter Scott for pointing to Randal Schwartz's answer on =

C.L.P.M.
>
>

http://groups.google.com/groups?hl=...lm=3D86hds1fa6=
n.fsf%40blue.stonehenge.com
>
> [SOLUTION]
> use List::Util from CPAN
> http://search.cpan.org/~gbarr/Scala...ib/List/Util.pm
>
> basically you use the module to create a group of numbers (like a card

deck)
> and then "deal" them randomly into an array.




--=20
To unsubscribe, e-mail: beginners-unsubscribe@perl.org
For additional commands, e-mail: beginners-help@perl.org
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Randy W. Sims

2004-07-28, 8:56 pm

Zeus Odin wrote:
> If you want to do it without the use of a module, you could
>
> (1) add the 15 numbers to an array (the deck)
> (2) choose a random number from the deck
> (3) remove that random element and add it to another array (your hand)
> (4) repeat until done (your hand has 10 numbers)
>
> This sounds exactly like the solution below sans module:
>
> #!/usr/bin/perl
> use warnings;
> use strict;
>
> my @nums = 1 .. 15;
> my @ten;
>
> for (1 .. 10) {
> push @ten, splice @nums, int(rand @nums), 1;
> }
> print "@ten";


Hmm, I may be wrong, but I don't think this is as random as it could be.
The problem is that every time you remove an element from the list, you
shrink the sample size. So the first selection is more random that the
next, and that selection more random than the next, etc.

A better approach is to perform a Fisher-Yates shuffle on the list and
then pop N elements from the list. This is what List::Util does.

Randy.
Zeus Odin

2004-07-28, 8:56 pm

Randy,

You are absolutely correct. Perl's rand function is not a random as it could
be. List::Util (via Fisher-Yates) is definitely more "random." However, the
original problem placed the contraint of not repeating any numbers. So with
every number chosen, you invariably shrink the number of choices left.

I see this problem exactly like picking numbers for a lottery drawing. If
there are 50 numbers (1-50) total and 6 winning numbers, after you choose
the first number there are 49 left to choose from. After the second pick,
there are 48 choices left, etc. I don't think anyone would suggest that a
lottery drawing is not completely random.... Although conspiracies abound!

The bottom line (or so I think) is that List::Util's algorithm for
randomness is better (more random) than Perl's rand() function.

Am I making sense?

Thanks,
Michael

-----Original Message-----
From: Randy W. Sims [mailto:ml-perl@thepierianspring.org]
Sent: Tuesday, July 27, 2004 6:21 AM
To: Zeus Odin
Cc: beginners@perl.org
Subject: Re: [SOLUTION] how can i generate 10 unique (non repeating) numbers

Hmm, I may be wrong, but I don't think this is as random as it could be.
The problem is that every time you remove an element from the list, you
shrink the sample size. So the first selection is more random that the next,
and that selection more random than the next, etc.

A better approach is to perform a Fisher-Yates shuffle on the list and then
pop N elements from the list. This is what List::Util does.

Randy.


Zeus Odin

2004-07-28, 8:56 pm

my %ten;
$ten{ rand() } = undef until scalar keys %ten == 10;
print "$_\n" for keys %ten;

Keep in mind, as Randy Sims pointed out, rand() is not truly random, but it
is random enough for me.
;-)

-----Original Message-----
From: N, Guruguhan (GEAE, Foreign National, EACOE)
[mailto:Guruguhan.N@geind.ge.com]
Sent: Tuesday, July 27, 2004 5:37 AM
To: Zeus Odin; beginners@perl.org
Subject: RE: [SOLUTION] how can i generate 10 unique (non repeating) numbers

Hi Zeus,
Your code and explanation are good. Incase I want 10 non
repeated random numbers between 0 and 1 what needs to be done?


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com