PWC 251
PWC 251
This time I tried both challenges using antique software on DOSBOX: Perl 4.019 for DOS, and for comparison Python 1.4 beta for DOS. My solutions also run on the current versions of Perl 5 (5.38) and Python 2 (2.7.18). Hooray for backward compatibility!
Challenge 1 (Concatenation Value)
Links to solution: Perl Python
We are given a list of positive integers, say ints. We are asked to follow the following procedure:
- Concatenate ints[0] and ints[-1] (last element). Store the result in retval say.
- Concatenate ints[1] and ints[-2] (second-last element), and add the result to retval.
- Concatenate ints[2] and ints[-3] .... etc. until we have reached the middle of the list.
- Return retval.
Here is the Perl 4.019 subroutine (it also works fine on the latest Perl 5.38).
sub concatenation_value {
local(@ints)=@_;
local($x,$retval)=(0,0);
foreach $x (0 .. @ints/2-1) {
$retval += $ints[$x] . $ints[$#ints-$x];
}
(@ints % 2) && ($retval += $ints[$#ints/2]);
return $retval;
}
We loop through the list concatenating items as described above. If there is an odd number of items, there is an extra step to add the single item in the middle of the list.
Here is the equivalent Python 1.4b code. (It also runs fine on Python 2.7.18, though not on Python 3 of course.) We need to explicitly convert the numbers to strings before concatenating, and then we need to explicitly convert the concatenated numbers from string to integer using the string.atoi method when updating retval. (In later python versions, we can just use int(strval), but that was not possible in 1.4b and gives a syntax error.)
def concatenation_value( ints ):
retval=0
for i in range(int(len(ints)/2)):
concat = str(ints[i])+str(ints[len(ints)-i-1])
retval = retval+string.atoi(concat)
if ((len(ints) % 2) ==1):
retval = retval + ints[ len(ints)/2 ]
return retval
Challenge 2 (Lucky Numbers)
Links to solution: Perl Python
We are given a matrix (array of equal-length arrays) consisting of distinct numbers (no number repeated). We are asked to find a matrix element such that it is simultaneously the highest in its column and the lowest in its row. If there is no such element, we return -1.
The python code is easier as an array of arrays is directly available even in this early version. Here is my python function:
retval=-1;
ncol=len(inmatrix[0])
nrow=len(inmatrix)
for y in range(nrow):
for x in range(ncol):
if (inmatrix[y])[x]==max(column(inmatrix,x)) == min(inmatrix[y]):
retval = (inmatrix[y])[x]
break
return retval
retval=[]
for y in range(len(inmatrix)):
retval.append( (inmatrix[y])[colno] )
return retval
local ($nrow, $ncol, @data)=@_;
(scalar(@data)==$nrow*$ncol) || die "Matrix data input error: $!\n";
local (%matrix,$y,$x);
foreach $y (0 .. $nrow-1){
foreach $x (0 .. $ncol-1){
$matrix{ "$y,$x" } = shift(@data);
}
}
%matrix;
}
sub column {
local ($colno, %matrix)=@_;
local (@column) = @matrix { grep( $_ =~ /,$colno/, keys %matrix) };
@column;
}
sub row {
local ($rowno, %matrix)=@_;
local (@row) = @matrix { grep( $_ =~ /^$rowno,/, keys %matrix) };
@row;
}
local ($nrow, $ncol)=($_[0], $_[1]);
local (%matrix)=&matrix(@_);
local ($y, $x,$retval);
$retval=-1;
OUTER: foreach $y (0 .. $nrow-1) {
INNER: foreach $x (0 .. $ncol-1) {
local ($rowmin)=((sort {$a<=>$b;} &row($y, %matrix))[0]);
local ($colmax)=((sort {$b<=>$a;} &column($x, %matrix))[0]);
if (($matrix{"$y,$x"}==$rowmin) && ($matrix{"$y,$x"}==$colmax)) {
$retval = $matrix{"$y,$x"};
last OUTER;
} #if
} #INNER
} #OUTER
$retval;
}
Comments