in reply to Difference between two arrays

My approach was slightly different. Since "The first array always looks the same (ascending numbers from $x to $x + $y)", I decided to ignore the first array completely and just focus on what's wrong in the second. Here's my code:
#!/usr/bin/perl use strict; use warnings; my @array = (1,2,3,6,4,5,7,8,9); # UPDATED again, numeric sort my $smallest = (sort {$a <=> $b} @array)[0]; my $stored = shift @array; # UPDATED per bug report in reply # if ($stored != $smallest) { if ($stored != $smallest && $stored + 1 != $array[0]) { print "$stored appears to be in the wrong position\n"; exit; } foreach my $i (0 .. $#array) { if ($stored != $array[$i] - 1) { if ($array[$i] + 1 != $array[$i + 1]) { print "$array[$i] appears to be in the wrong position\n"; last; } } $stored = $array[$i]; }

---
It's all fine and dandy until someone has to look at the code.

Replies are listed 'Best First'.
Re^2: Difference between two arrays
by johngg (Canon) on Mar 22, 2006 at 17:24 UTC
    I'm not sure your if ($stored ne $smallest) {...} is correct, for two reasons. Firstly, ne is for string comparisons and these are numbers so != would be better. Secondly, and more importantly, I think your logic might be a bit suspect. In the original post the 1 was moved further up the list so that 2 was the first element. Thus, your

    $smallest = (sort @array)[0];

    would give us 1 but your

    $stored = shift @array;

    would result in 2. Your condition would be met, your script exits with an error but the move is a valid one.

    I think the only constraints were that a) the numbers are consecutive and b) one element is moved to form the new list. Thus in a list of 1 to 9, the 7 could be moved to the front giving 7,1,2,3,4,5,6,8,9 which would also fail in your script.

    Cheers,

    JohnGG

      != would be better

      Noted and changed, thank you.

      but the move is a valid one

      Why do you think this is a valid move? The author's original post doesn't state anything like that, and the author's replies to other solutions suggests that this is not a valid move.

      Update: I see the bug you were referring to and have updated my code accordingly. Thanks!

      ---
      It's all fine and dandy until someone has to look at the code.
        Well, I thought it was a valid move because it is exactly what happens in the original post.

        my $before = [qw(1 2 3 4 5 6 7 8 9 10)]; my $after = [qw(2 3 4 5 1 6 7 8 9 10)];

        Element 0, the 1, has been spliced out then spliced back in as element 4. rafl also says in his first reply "the items can move forwards and backwards in the list." Also, nowhere in the posts is any constraint placed on where an element can be moved from or to.

        There is another wee bugette in that the sort to find $smallest should be a numerical one:-

        my $smallest = (sort {$a <=> $b} @array)[0];

        otherwise @array = (4 .. 13); would come up with 10 as it's "smallest" item because lexically 10 comes before 4.

        If we accept that we can move a number to the beginning of the list I still think there is a problem with your logic. If we start with

        my @array = (7,1,2,3,4,5,6,8,9);

        we get a $smallest of 1 and a $stored of 7 and $array[0] is also 1. Applying your logic, 7 != 1 && (7 + 1) != 1 is true and you exit with the error.

        Cheers

        JohnGG