Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

While issues

by Dandello (Scribe)
on Feb 03, 2011 at 15:48 UTC ( #886010=perlquestion: print w/ replies, xml ) Need Help??
Dandello has asked for the wisdom of the Perl Monks concerning the following question:

I'm sure fresher eyes will come up with a better solution - or just tell me what's wrong with this

my $cnr = 0; while ($cnr < 1) { my $xda = int rand (0 .. $total); if ( $aob[$xda][ $y - 1 ] ne q{}) { $aob[$x][$y] = $z + $aob[$xda][ $y - 1 ]; $cnr++; } }

What this is supposed to do is find the first non-empty randomly chosen member of @aob line $y-1 (which has numbers and blanks) and assign that value plus $z to $aob[$x][$y]. Unfortunately,the script just sits with a blinking cursor at this section, so I assume it's in a loop.

Warnings and strict are on, no warnings.

Now, I do have a cludgy work around

Never mind - looking back at my cludgy work around and tweaking it:

my @delarray = ( 0 .. $total ) my $cnr = 0; my @dlarray = shuffle @delarray; for my $xd ( 0 .. $total ) { my $xda = $dlarray[$xd]; if ( $cnr <= 1 && defined $aob[$xda][ $y - 1 ] ) { $aob[$x][$y] = $z + $aob[$xda][ $y - 1 ]; $cnr++; } }

Comment on While issues
Select or Download Code
Re: While issues
by wind (Priest) on Feb 03, 2011 at 15:54 UTC

    Your problem is here:

    my $xda = int rand (0 .. $total);

    rand only takes a single parameter, so you're selecting a random number from 0 to 0 currently. This is probably what you intended:

    my $xda = int rand $total;

    -Miller

      Off by one. That will never return $total. rand returns a value that's "up to but not including" its argument.
Re: While issues
by kennethk (Monsignor) on Feb 03, 2011 at 15:55 UTC
    There is nothing fundamentally wrong with the while portion of the construct. My guess would be that your conditional $aob[$xda][ $y - 1 ] ne q{} never evaluates to true. Are you sure it contains what you think it does? See How can I visualize my complex data structure? (short answer Data::Dumper).

    On a side note, if $cnr is never used outside this context, I would use last (see Loop Control) to control flow:

    while (1) { my $xda = int rand (0 .. $total); if ( $aob[$xda][ $y - 1 ] ne q{}) { $aob[$x][$y] = $z + $aob[$xda][ $y - 1 ]; last; } }

    Update: I think windikegami has the answer abovebelow.

Re: While issues
by ikegami (Pope) on Feb 03, 2011 at 15:58 UTC
    rand(0 .. $total)
    should be
    rand($total+1)

    Actually, it probably be should be

    rand(0+@aob)

    If any element of @aob can be picked, why rely on some external value.

    (Technically, the "0+" is unnecessary because of rand's prototype, but that's fairly obscure.)

    By the way, $cnr is unneeded. I also got rid of q{} because it just doesn't stand out as much as the default quotes.

    while (1) { my $xda = int rand( 0+@aob ); if ( $aob[$xda][ $y - 1 ] ne "") { $aob[$x][$y] = $z + $aob[$xda][ $y - 1 ]; last; } }
Re: While issues
by Dandello (Scribe) on Feb 03, 2011 at 16:07 UTC

    So many good solutions, and so much better than my cludge

    I knew it was something dumb and simple - I rarely bollux up the complicated ones, but simple...

    And ikegami's solution worked like a charm.

    Thank you

Re: While issues
by ikegami (Pope) on Feb 03, 2011 at 16:08 UTC

    The code in your update is functionally different than your original code. Did you mean to go from finding one non-empty element to two? (original: $cnr < 1 vs new: $cnr <= 1).

    Also, it loops more than necessary. The following fixes this and simplifies the code:

    my $cnr = 2; for my $xda ( shuffle 0 .. $total ) { if ( defined $aob[$xda][ $y - 1 ] ) { $aob[$x][$y] = $z + $aob[$xda][ $y - 1 ]; last if --$cnr == 0; } }

    Or if you mean to only find one non-empty element:

    for my $xda ( shuffle 0 .. $total ) { if ( defined $aob[$xda][ $y - 1 ] ) { $aob[$x][$y] = $z + $aob[$xda][ $y - 1 ]; last; } }

      Your initial solution was SO much better than mine. So that's the one I'm using.

      I needed to find the first random non-blank element. Using shuffle worked, but I was looking for a neater and simpler way.

      Again, thank you.

      My final -

      while (1) { my $xda = int rand $total + 1; if ( defined $aob[$xda][ $y - 1 ] ) { $aob[$x][$y] = $z + $aob[$xda][ $y - 1 ]; last; } }
      . Using 'defined' is actually better in this case than using "" or q{}. No warnings.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://886010]
Approved by kennethk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2014-09-30 23:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (385 votes), past polls