Mac Random Number, Perl Question

fivetoadsloth

macrumors 65816
Original poster
Aug 15, 2006
1,037
0
Hey, I'm trying to generate random strings with numbers from 1-100. I have the following code:
Code:
sub generate_random_string
{
        my $length_of_randomstring=10;               

        my @chars=('1'..'100');
        my $random_string;
        foreach (1..$length_of_randomstring)
        {
                $random_string.=$chars [rand @chars];
        }
        return $random_string;
}

my $random_string=&generate_random_string(11);

print  " .$random_string."\n";
Which works fine, but I'd like to have something separating the different numbers. For examples rather then having eight, eleven, three be 8113 print as 8,11,3 or 8 11 3, or something similar.


Thanks.
 
Last edited:

chown33

Moderator
Staff member
Aug 9, 2009
8,497
4,459
Pale blue comma
This is pretty simple to solve if you just break it down.

You want a delimiter before the random number. So append whatever delimiter you want to the string, then append the random number.

There is an edge case at the beginning, but that problem will also yield if you break it down.
 

kainjow

Moderator emeritus
Jun 15, 2000
7,745
3
Code:
$random_string.=$chars [rand @chars];
In Perl the . is used to concatenate strings, so you can add on to this statement like so:
Code:
$random_string.=$chars [rand @chars] . " ";
That will add a space after each random character.
 

balamw

Moderator
Staff member
Aug 16, 2005
19,095
963
New England
If the leading/trailing delimiter bothers you, get rid of it using substr.

Code:
$random_string = substr($random_string, [B][0/1][/B], (length($random_string)-1));
Use 0 to remove a trailing delimiter, 1 to remove a leading delimiter.

B
 

fivetoadsloth

macrumors 65816
Original poster
Aug 15, 2006
1,037
0
This is pretty simple to solve if you just break it down.

You want a delimiter before the random number. So append whatever delimiter you want to the string, then append the random number.

There is an edge case at the beginning, but that problem will also yield if you break it down.
Sorry, yeah. I see it now.

Code:
$random_string.=$chars [rand @chars];
In Perl the . is used to concatenate strings, so you can add on to this statement like so:
Code:
$random_string.=$chars [rand @chars] . " ";
That will add a space after each random character.
Thanks a lot.
 

chown33

Moderator
Staff member
Aug 9, 2009
8,497
4,459
Pale blue comma
If the leading/trailing delimiter bothers you, get rid of it using substr.

Code:
$random_string = substr($random_string, [B][0/1][/B], (length($random_string)-1));
Use 0 to remove a trailing delimiter, 1 to remove a leading delimiter.

B
There's also a nice way to avoid adding unnecessary delimiters. The logic goes like this:
Code:
string between = "";
string building = "";
for every item to append:
  building = building + between + item;
  between = ",";  // or delimiter of choice
loop
 

balamw

Moderator
Staff member
Aug 16, 2005
19,095
963
New England
There's also a nice way to avoid adding unnecessary delimiters.
Sure, or simply adding the first (or last) item outside the loop. e.g.

Code:
string between = ",";
string building = first item;
for every remaining item to append:
  building = building + between + item;
loop
I was just trying to apply an independent fix.

B
 

fivetoadsloth

macrumors 65816
Original poster
Aug 15, 2006
1,037
0
Sorry, one more question. I got the above working fine and am outputting to a txt file. I'm now trying to read in the text file and replace certain ranges of numbers with different characters.

I have the following:
Code:
open(IN, "tmp.txt");
$index=0;
while(<IN>){
        chop;  @info=split;
        $string=$info[0];
        $string =~ s/[1-4]/A/g;
        $string =~ s/[5-7]/B/g;
        $string =~ s/[8-100]/C/g;
        $index++;
        print("$string \n");
}
However, I think that the [8-100] construction doesn't make sense, and each digit will be replace individually rather then in two or three digit sets.

I tried the following construction instead, but it wasn't working either:
Code:
'8'..'100'
The second problem is the tmp.txt file is in this format:
33 54 3 94 86 9 16 98 3 49 90 64 32 36
and the code is only reading in the first number (33). I realize the problem is that when I break it into an array the first element is all that I am looking at, which is wrong. I can I make it go through the entire array?

Sorry! I'm trying to work though this with a perl book in front of me, but the examples are relatively limited.
 
Last edited:

fivetoadsloth

macrumors 65816
Original poster
Aug 15, 2006
1,037
0

ChOas

macrumors regular
Nov 24, 2006
139
0
The Netherlands
Thanks a lot. I actually came up with a less elegant solution- in the random number program I printed a new line character and then just went through them one line a time.

I'm still not sure as to how I can have different number ranges be replaced by different characters.
Well, Like you found out you can't easily (or at all) use a character class to
do that. You would either use split and go through some if elses or you start playing dirty/unreadable and do something like this:

Code:
#!/usr/bin/perl -w

use strict;

my $test = '1 3 5 60 3 4 5 10 99 7 101';
   $test=~s/(\d+)/($1<4)?'A':($1<10)?'B':($1<100)?'C':'X'/eg;

print $test,"\n";
Output:

Code:
A A B C A B B C C B X
Numbers below 4 are replaced by A, numbers between 4 and 10 by B, numbers between 10 and 100, C, and higher than 100, by X.

Still, I have the feeling we are dealing with an XY problem. What is it you actually need to do ?
 

balamw

Moderator
Staff member
Aug 16, 2005
19,095
963
New England
Still, I have the feeling we are dealing with an XY problem. What is it you actually need to do ?
Yup. And read http://www.mikeash.com/getting_answers.html as well.

FWIW in languages without a real boolean I prefer to separate the ranging from the translating. i.e. something like

Code:
$range=($n>4)+($n>10)+($n>40))
which will give you a number from 0-3 from 0-100 and you can use that with an array to translate the ranges to strings trivially.

B