Random Number, Perl Question

Discussion in 'Mac Programming' started by fivetoadsloth, Mar 3, 2011.

  1. fivetoadsloth, Mar 3, 2011
    Last edited: Mar 3, 2011

    fivetoadsloth macrumors 65816

    fivetoadsloth

    Joined:
    Aug 15, 2006
    #1
    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.
     
  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    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.
     
  3. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #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.
     
  4. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #4
    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
     
  5. fivetoadsloth thread starter macrumors 65816

    fivetoadsloth

    Joined:
    Aug 15, 2006
    #5
    Sorry, yeah. I see it now.

    Thanks a lot.
     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    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
     
  7. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #7
    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
     
  8. fivetoadsloth, Mar 3, 2011
    Last edited: Mar 3, 2011

    fivetoadsloth thread starter macrumors 65816

    fivetoadsloth

    Joined:
    Aug 15, 2006
    #8
    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:
    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.
     
  9. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
  10. fivetoadsloth thread starter macrumors 65816

    fivetoadsloth

    Joined:
    Aug 15, 2006
    #10
  11. ChOas macrumors regular

    Joined:
    Nov 24, 2006
    Location:
    The Netherlands
    #11
    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 ?
     
  12. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #12
    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
     
  13. Hansr macrumors 6502a

    Joined:
    Apr 1, 2007
    #13
    Reading this post I realize how little I miss Perl.
     
  14. ChOas macrumors regular

    Joined:
    Nov 24, 2006
    Location:
    The Netherlands
    #14
    Hey! That's not nice!

    I could have suggested:

    Code:
    sub generate_random_string_of_length {
      join ' ',map {(1..100)[rand 100]} 1..$_[0];
    };
    
    print generate_random_string_of_length(10) ,  "\n";
    
    ;)
     

Share This Page