I think a good first step would be to clean up your logic a bit. You've got two while ($all_the_numbers<20) loops, but $all_the_numbers is initialized as a random number from 0 to 18 and never changed - so those are essentially infinite loops. You exit them via last and the loop counters $i and $h, so really, those two loops can be replaced by for loops. More specifically, in the following I've used the more Perlish foreach loop with a range operator, and since you only use the variables $i and $h to ensure the loop runs $all_the_numbers times, I've removed those variable names entirely. The new loops have an added benefit: in your original code, if $all_the_numbers was zero, your code would drop into an infinite loop - maybe you can see why? (Hint: Add a say $i; right before the comparison to $all_the_numbers.)

#!/usr/bin/env perl use warnings; use strict; use feature qw/say/; my $all_the_numbers=int(rand(19)); say "$all_the_numbers"; my @rand=(); for (1..$all_the_numbers) { push @rand, 20-int(rand(30)); } say "@rand"; for (1..$all_the_numbers) { for (@rand) { if ( $rand[0]<0 ) { next; } # skip the negative ones shift @rand; } } say "@rand";

Now, I hope that's easier to read. As for your logic: Note that shift removes the first item off the list, not the current one. If you wanted to do that, you'd need to do something like splice, however, that's tricky because it edits the array you're currently looping over, changing the indices. You said "this resoults in deleting only the positive numbers" - notice that your logic currently says: "Loop over the elements of @rand, each time checking if the first element of @rand is less than zero, and if it is, skip the rest of the loop (i.e. the shift)". Skipping the rest of the loop can also be expressed as follows*: "Loop over the elements of @rand, each time testing the first element of @rand, if that element is greater than or equal to zero, remove it from the array." I hope this explanation helps make it clear what is going wrong?

Now, as for how to fix it, I think I have to suggest re-thinking your overall logic. This is one of those cases where working out the issue on paper would be beneficial, especially if you are required to operate on the array in-place. For each iteration of the loop, keep track (on paper) of the loop counter, the contents of the array, which item you want to remove, and so on. If you are not required to operate on the array in-place, then Perl provides a handy function to make the task of keeping only certain items of an array very easy - have a look at grep.

* Update: Breaking that down:

for (@rand) { if ( $rand[0]<0 ) { next; } shift @rand; }

Can be written as:

for (@rand) { if ( $rand[0]<0 ) { next; } else { shift @rand; } }

Which can be written as:

for (@rand) { if ( $rand[0]>=0 ) { shift @rand; } else { next; } }

And the else { next; } can be removed.

Update 2: Added more links to text, and minor changes to wording.


In reply to Re: Deleting certein elements from an array by haukex
in thread Deleting certein elements from an array by Eso

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.