PWC 228
PWC 228
Challenge 1 (Unique Sum)
We are given an array of integers, and asked to return the sum of only those elements that are unique, i.e., skipping any elements that are repeated.
I use a single pass through the array, adding elements as I go, and also counting their frequency with a hash. If the frequency hits 2, then I subtract the element from the running total, and thereafter ignore any further repetitions. I use the ( a ? b : c ) conditional expression.
Here is the subroutine:
my @int = @_;
#-- %int : hash to count frequency of each element of @int,
#-- $retval : return value
my (%int, $retval);
#initialize %int values, $retval, to zero
$retval=0;
map {$int{$_}=0} @int;
#-- loop thru' @int counting frequencies and updating $retval
map {
$int{$_}++;
($int{$_} > 1) ?
( ($int{$_} == 2) ? ($retval -= $_) : 1 )
: ($retval += $_);
} @int;
$retval;
}
Challenge 2 (Empty array)
We are given an array of unique integers. Then we take the first element in the array. If it is the minimum element, we remove it (shift). Otherwise, we move it to the end of the array (shift then push). Repeat until the array is empty. We are asked to return how many steps this will take.
Since we just need to return the count rather than run through the procedure directly, we can note that if the minimum element is at position x (indexed from 0), then we need x+1 steps to take this element out (x steps to move the preceding elements, and 1 more step to shift the minimum element). For example, if the array is [3,4,2], we need 3 steps to reduce it to [3,4] (The element 2 is at position 2, so 2+1 steps to remove the element 2).
We can now repeat the calculation with the reduced array. We need a further 1 step (index 0 + 1) to get rid of 3, and reduce to [4]. And so on (one more step to empty the array).
Here is the subroutine:
my @int=@_;
my $retval=0; #-- return value
#-- assuming unique ints
#-- skipping input validation chores
my %indx;
#-- %indx: index of each element
my @int_sorted = sort {$a <=> $b} @int;
while (scalar @int) {
map {
$indx{$int[$_]} = $_;
} 0 .. $#int;
$retval += $indx{$int_sorted[0]} + 1;
splice(@int,$indx{$int_sorted[0]},1);
shift(@int_sorted);
}
$retval;
}
Comments