This code snippet will produce strings of numbers (1 thru 49) with no repeated numbers in the same string and no duplicated string of numbers in the list of strings. To change the range of numbers the script generates change 49 in the code to your requirements.

Please feel free to ask questions or post comments about this snippet of code.

use warnings;
use strict;

my $length = 7; # the amount of numbers per string
my $max = 1000; # the number of strings
my @strings; # array to store the strings
for (1..$max) {
   push @strings, rand_nums($length);
print "$_\n" for @strings;

   my %cache; # create a "static" variable
   sub rand_nums {
      my %local_cache; # create a new hash
      my ($length) = @_; # the length of the random number string passed to the sub
      my $serial = int(rand(49))+1; # get the first number for the serialized string
      $local_cache{$serial} = 1; # store the first number in the hash
      for (2..$length) {# start at 2 because we already have the first number
         my $num = int(rand(49))+1; # get a new random number
         redo if exists $local_cache{$num}; # redo the loop if the number already exists
         $local_cache{$num} = 1; # store the number in the hash
         $serial .= "-$num"; # append to the serialized string
      rand_nums($length) if exists $cache{$serial}; # redo the function if the key already exists
      $cache{$serial}=1; # store the new key in the hash (%cache)
      return $serial;
9 Years
Discussion Span
Last Post by KevinADC

could you make this sample the random numbers without replacement? like once you've used #s 2 4 6 8 10 12 14 in your first 7 digit string, the next string doesn't contain those numbers? i'm pretty new to perl and piecing things together slowly... creating unique strings of random numbers is my ultimate goal. any help would be great. thanks!


The code already produces unique strings of random numbers so I am not sure what you are asking.


sorry to be unclear. i'm trying to generate strings of numbers, that once a number has been used in one of the strings, it is not used in the next. i've been working on it and think my problem is a much simpler one than this code necessitates...i just want to distribute all of the numbers between 1 and 49 into strings (ideally of random length) until they're all gone. any help would be awesome...hope that makes more sense. thanks.


If you do that you can only have 7 strings of random numbers. What you want to do is much easier than the code I posted. All you have to do is shuffle an array of numbers and then split the array into strings of n length (7 in this case). You can use List::Util to shuffle the array and a loop to assign the numbers to strings, something like:

use strict;
use warnings;
use List::Util 'shuffle';
my @nums = shuffle(1..49);
my @rand_nums;
for (my $n = 0; $n < 48; $n+=7) { 
   push @rand_nums, join('-',@nums[$n..$n+6]);
print "$_\n" for @rand_nums;
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.