[SOLVED] Looking for code to generate 6 random numbers between 1 and 47.
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Then the short way is to add in sort as in hydrurga's sed example. Or if you want to keep it all inside perl, there are several ways, but trickier to read:
Then the short way is to add in sort as in hydrurga's sed example. Or if you want to keep it all inside perl, there are several ways, but trickier to read:
linustalman asked for a way to output the numbers on the same line and separated by commas.
tr was my first attempt but it tacks on a trailing comma. paste doesn't cause that blemish.
Daniel B. Martin
I agree you got a way to eliminate that. Good Job but he never said he didn't want extra , plus that way too doesn't not give an "\n" at the end either, not in my term anyways. personally I'd go with yours.
( i didn't look through every single one before posting... my bag ...
Then the short way is to add in sort as in hydrurga's sed example. Or if you want to keep it all inside perl, there are several ways, but trickier to read:
obviously that was incorrect, but here is a better version (now it sorts the "result" too):
Code:
my %l = map { $_ => int(rand($range)) } (1..47);
The problem with this approach is that there's no guarantee that the map array will not contain duplicate values. (In fact, it probably will.)
If you need to produce a randomly-arranged sequence of numbers with no duplicates, the best algorithm I've seen mimics "shuffling a deck of cards." A cursor walks the array from stem to stern, and a card is chosen at random from a position prior to or equal to that of the cursor. This card is then exchanged with the one at the cursor position. In a single pass, the "deck" is shuffled completely. The desired number of random values are then "drawn" from either end of the deck.
But if I only needed six values, and I was never going to need six more, to go to this amount of trouble is unnecessary. Simply generate six values. Then, comb through them looking for dupes. Replace any dupes with randomly-chosen values and "rinse and repeat" until there are no dupes. If the number of values needed (6) is very-small in relation to their range (1..42), the odds are in your favor.
Last edited by sundialsvcs; 05-01-2017 at 01:34 PM.
The problem with this approach is that there's no guarantee that the map array will not contain duplicate values. (In fact, it probably will.)
Yes, but that is not a problem. The value of $range is not important, and also int() is not really required. But it will make this (implementation) a bit more expressive I think.
The trick is I shuffle the indices, not the values. That map array is (values are) only used to shuffle the indices of %l (the keys), which are unique. That means I will reorder them by values, and I do not really care if the values are the same, they will be [re-]ordered/sorted anyway). This is how shuffle should work I think.
As you can see in the last line I use the variable shuffled_keys to get 6 numbers.
post #68 is simply wrong, overcomplicated and sometimes it also drops an error message too.
Yes, but that is not a problem. The value of $range is not important, and also int() is not really required. But it will make this (implementation) a bit more expressive I think. The trick is I shuffle the indices, not the values. [...]
A deck of cards must not contain duplicates. Whether you shuffle the indices or shuffle the numbers, the result of drawing every single card in the deck must "probably, never" produce an identical card.
If you call rand(42) 42 times, you will get duplicates: (The output shown below has been reformatted into six-digit groups.)
Nevertheless, if you simply need six numbers, you can simply produce six and check for duplicates. In the example above, the first six numbers contain no duplicates. In fact, only one of the 6-digit groups contains a duplicate value within itself. (The probability of this is about 50%.)
Furthermore, the choice of algorithm could have subtle statistical implications, if, say, you were performing this loop repeatedly to take "random samples" from a population. If you shuffled a deck of 48 cards, and drew 6 cards from the deck 8 consecutive times, then each of the 8 samples would contain no elements in common. Which is not the same as generating 8 consecutive random groups each one of which contains no duplicates. In the list above, "31" would be sampled twice, likewise "1" and "11" and so on, although each 6-element sample is individually "random." In one case, the draws are causally related to all other draws in the same 8-draw group; in the second, they are not. So, it depends upon what you actually want to do.
Last edited by sundialsvcs; 05-03-2017 at 09:11 AM.
you still did not catch the trick:
initially I have 47 integers (1..47) and associated 47 random number (these random numbers are irrelevant, almost anything can be used, int(rand($range)) is just one possibility - the only thing we need is to generate more or less different numbers)
Code:
%l = (1 => random, 2 => random, .... )
Then I shuffle the keys of %l by sorting based on values. That is
Code:
my @shuffled_keys = sort { $l{$a} <=> $l{$b} } keys(%l);
this will randomize the keys, and the values will be ordered (ascending). We may have equal values, I do not really care about that, but we still cannot have duplicates on keys.
And finally I need six items, that is:
Code:
@shuffled_keys[1..6]
# or
@shuffled_keys[19..25]
# or any similar
# and finally I sort and print it:
print join (", ", sort { $a <=> $b } @shuffled_keys[1..6]);
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.