PWC 142 task 1: You are given positive integers, $m and $n. Write a script to find total count of divisors of $m having last digit $n.
Tasks such as this always raise a dilemma. Do I write something ingenious and compact, or should I write code which someone else (or me in 10 years) can easily understand.
My submission falls in the second category. I simply loop $j from 1 to $m, checking whether $m / $j is an integer, in which case $j is a divisor. I add that to my list of divisors, and if it ends in $n, to my list of divisors ending in $n.
This is - in once sense - quite inefficient, because once $j exceeds $m/2 the only remaining divisor is $m itself so I've wasted more-or-less half my time.
I could get round that by looping $j from 1 to int($m/2), and every time I found a divisor $d I could add $d and $m/$d to my list of divisors. But then I would have to sort the list, or possibly make two lists, reverse one of them and concatenate, remembering that if $m is even, $m/2 will be in my list twice.
Even faster would be to check only for prime divisors, and then there would be quite a limited set of combinations of those which would need to be tested for last-digit matching.
So I went with the simple version, and even my little Raspberry Pi easily deals with, for example, 1048575 in a couple of seconds.
No doubt someone - probably many people - will have come up with a more elegant solution, and of course if my solution had been very slow I would have done that too.
One of the failings of Perl code which is often mentioned is its maintainability. I've been at both ends of that - writing code which I know will need to be maintained to meet changing business needs long after I'm gone, and being tasked with maintaining code that some long-gone person wrote.
I know which approach I prefer.
PWC 142 task 2: Write a script to implement SleepSort.
This is of course a bit of a joke, but you can do it in Perl, of course. I found that delaying $n seconds worked, but much less, for example $n/10 seconds did not: the Linux scheduler clearly doesn't use a fifo queue.
There is a slightly less jokey way of sorting in Perl without actually sorting:
@list = (1, 9, 76, 3, 99, 4, 22);
for $j (@list) {
$sorted[$j] = 1;
$max = $j if $j > $max;
}
for $j (0 .. $max) {
say qq[$j] if $sorted[$j];
}
No comments:
Post a Comment