Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
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
Replies are listed 'Best First'.
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 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 (Abbot) 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 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.

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

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 scrutinizing the Monastery: (17)
As of 2015-07-28 19:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (258 votes), past polls