I am trying to splice the array on the copy and not original array But looks like the loop ends before it can read the next 6 in the list
It's not the loop ending prematurely, it is wrong indices.
This happens because splice shrinks the array @copy, and after that, the original and copy arrays aren't aligned any more. You need yet another variable which holds the amount of elements spliced off, and decrease $sixindex by that amount at the next splice operation, otherwise the offset is outside the @copy array.
Adding some debug print statements shows the problem:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dump;
########
my $aref = [1, 6, 2, 2, 7, 1, 6, 99, 99, 7];
my $flag = 0;
my $i = 1;
my $sixindex = 0;
my @copy = @$aref;
if (scalar(@$aref) >= 2) {
foreach my $x (0..$#{$aref}) {
print "pass $x\n";
dd $aref;
dd \@copy;
if (defined($aref->[$x])) {
if ($aref->[$x] == 6) {
$flag = 1;
$sixindex = $x;
next;
}
if ($flag) {
unless ($aref->[$x] == 7) {
$i++;
next;
} elsif ($aref->[$x] == 7 ) {
print "splice $sixindex, ",($i+1),"\n";
splice(@copy, $sixindex, $i + 1);
$flag = 0;
$i = 1;
$sixindex = 0;
next;
}
}
}
}
}
dd \@copy;
__END__
pass 0
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7]
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7]
pass 1
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7]
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7]
pass 2
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7]
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7]
pass 3
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7]
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7]
pass 4
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7]
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7]
splice 1, 4
pass 5
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7]
[1, 1, 6, 99, 99, 7]
pass 6
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7]
[1, 1, 6, 99, 99, 7]
pass 7
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7]
[1, 1, 6, 99, 99, 7]
pass 8
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7]
[1, 1, 6, 99, 99, 7]
pass 9
[1, 6, 2, 2, 7, 1, 6, 99, 99, 7]
[1, 1, 6, 99, 99, 7]
splice 6, 4
[1, 1, 6, 99, 99, 7]
The second splice at pass 9 has an offset of 6, but the last element of @copy is at index 5. Pass 4 spliced off 4 elements, so you want offset 2 here (6 - 4).
This does what you want:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dump;
########
my $aref = [1, 6, 2, 2, 7, 1, 6, 99, 99, 7];
my $flag = 0;
my $i = 1;
my $sixindex = 0;
my $spliced = 0;
my @copy = @$aref;
if (scalar(@$aref) >= 2) {
foreach my $x (0..$#{$aref}) {
print "pass $x\n";
dd $aref;
dd \@copy;
if (defined($aref->[$x])) {
if ($aref->[$x] == 6) {
$flag = 1;
$sixindex = $x;
next;
}
if ($flag) {
unless ($aref->[$x] == 7) {
$i++;
next;
} elsif ($aref->[$x] == 7 ) {
print "splice ",$sixindex-$spliced, " ",($i+1
+),"\n";
splice(@copy, $sixindex-$spliced, $i + 1);
$spliced += $i + 1;
$flag = 0;
$i = 1;
$sixindex = 0;
next;
}
}
}
}
}
dd \@copy;
All that indexing stuff is only necessary because you make a copy of the array and delete the ignored elements later. Is that a requirement of the homework? If not, you could drop all that index counting and track keeping stuff, and just push the elements not to be ignored onto @copy :
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dump;
########
my $aref = [1, 6, 2, 2, 7, 1, 6, 99, 99, 7];
my $flag = 0;
my @copy;
if (scalar(@$aref) >= 2) {
foreach my $x (@$aref) {
dd $aref;
dd \@copy;
if (defined($x)) {
if ($x == 6) {
$flag = 1;
next;
}
if ($flag) {
next unless $x == 7;
$flag = 0;
next;
}
print "push \@copy,$x\n";
push @copy, $x;
}
}
}
dd \@copy;
The only helper variable left now is $flag. But Perl has the ".." range operator which acts like a flip-flop, and as such has the $flag boolean built-in. Using that:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dump;
########
my $aref = [1, 6, 2, 2, 7, 1, 6, 99, 99, 7];
my $flag = 0;
my @copy;
if (scalar(@$aref) >= 2) {
foreach my $x (@$aref) {
dd $aref;
dd \@copy;
if (defined($x)) {
if ($x == 6 .. $x == 7) {
next;
}
print "push \@copy,$x\n";
push @copy, $x;
}
}
}
dd \@copy;
Condense that a bit further, and you have tybalt89's solution.
perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'