Jim,
Jim said:
I'm trying to find an efficient way of finding the lowest value of an
array but starting at a given index. For example:
@array = (0, 0, 1, 2, 0, 1, 1, 1);
<SNIP>
My attempt outputs this:
Scan from element 1 (index 0)
[1,2,3,4,5,6,7,8][]
[0,0,1,2,0,1,1,1][]
Lowest value is 0
at element 1
Scan from element 3 (index 2)
[3,4,5,6,7,8][1,2]
[1,2,0,1,1,1][0,0]
Lowest value is 0
at element 5
Scan from element 6 (index 5)
[6,7,8][1,2,3,4,5]
[1,1,1][0,0,1,2,0]
Lowest value is 0
at element 1
That gets the answers you want.
Any suggestions on an efficient way to do this? Thanks...
"Efficient" compared with what?
It is conventional for you to show us what you have tried.
Otherwise, respondents cannot compare efficiency of their algorithms with
yours.
(And there is the lurking suspicion that you might have tried nothing at
all.
Such a case is often described as a "homework question".)
I used "splice", "push", and a "for"-loop, which are simple enough, but I
make no claims for great efficiency.
How many elements might you encounter in the array in your production
program?
FWIW, my code is below. (Excuse the length of this posting, people.)
Regards,
Clyde
#!/bin/perl -w
use strict;
use Data:
umper;
local $Data:
umper::Terse = 1;
local $Data:
umper::Indent = 0;
my @array = ( 0, 0, 1, 2, 0, 1, 1, 1 );
my @indices = ( 0, 2, 5 );
for my $index ( @indices ) {
# We are going to skip the leading elements of the array, and
# start our scan from the given index.
# $index numbers from 0 (e.g.: 5)
# $element_nr numbers from 1 (e.g.: 6)
my $element_nr = $index+1;
print "\nScan from element $element_nr (index $index)\n";
my @arr = @array; # Copy array, before splicing it
if ( ($index < 0) or ($index > $#arr) ) {
warn "$index: index out of range 0..$#arr. Ignoring\n\n";
next;
}
# Remember ranges of element numbers in skipping and starting portions
# e.g.: (1..5) and (6..8)
my @skipping_element_nrs = ( 1 .. ($element_nr - 1) );
my @starting_element_nrs = ( $element_nr .. (scalar @arr ) );
# Remove the leading $index elements of @arr, into new array @skip
# e.g.: for index 5, we will skip elements (1..5)
my @skip = splice( @arr, 0, $index );
# Print out 2 arrays of element numbers, one from the starting element
# to the end, the second for the element numbers we skipped.
# e.g.: [6,7,8][1,2,3,4,5]
print Data:
umper->Dump( [
\@starting_element_nrs, \@skipping_element_nrs ] ) . "\n";
# Then print corresponding 2 arrays of elements
# e.g.: [1,1,1][0,0,1,2,0]
print Data:
umper->Dump( [\@arr, \@skip] ) . "\n";
# Push the skipped elements onto the end of @arr
push( @arr, @skip );
# Scan the re-formed array @arr for the lowest value and its index
my $new_index_of_lowest = 0;
for my $i (1 .. $#arr) {
$new_index_of_lowest = $i if ($arr[$i] <
$arr[$new_index_of_lowest]);
}
# Work out element nr of lowest, with respect to original array,
# remembering that search wraps around the end of the array
my $old_element_nr_of_lowest = ($new_index_of_lowest+$index)%(scalar
@arr)+1;
print "Lowest value is $arr[$new_index_of_lowest]\n";
print "at element $old_element_nr_of_lowest\n";
}
(End of response)