Last digit sleeps
Weekly challenge 142 — 6 December 2021
Week 142: 6 Dec 2021
You are given positive integers, $m
and $n
.
Write a script to find total count of divisors of $m
having last digit $n
.
Example 1: Input: $m = 24, $n = 2 Output: 2 The divisors of 24 are 1, 2, 3, 4, 6, 8 and 12. There are only 2 divisors having last digit 2 are 2 and 12. Example 2: Input: $m = 30, $n = 5 Output: 2 The divisors of 30 are 1, 2, 3, 5, 6, 10 and 15. There are only 2 divisors having last digit 5 are 5 and 15.
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 (1 .. $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 (1 .. 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.
#!/usr/bin/perl # Peter Campbell Smith - 2021-12-08 # PWC 142 task 1 use v5.20; use warnings; use strict; my ($test, @tests, $m, $n, $string1, $string2, $divisor, $dividend, $count, $s); # inputs - pairs of $m and $n @tests = ([24, 2], [30, 5], [24, 7], [37, 0], [45, 5], [1048575, 5], [1048576, 2]); # loop over tests for $test (@tests) { ($m, $n) = @$test; say qq[\nInput: \$m = $m, \$n = $n]; $count = 0; $string1 = $string2 = ''; # loop over potential divisors for $divisor (1 .. $m) { $dividend = $m / $divisor; # if it is a divisor if ($dividend eq int($dividend)) { $string1 .= qq[$divisor, ]; # list of all divisors if ($divisor % 10 == $n) { $string2 .= qq[$divisor, ]; # list of divisors with last digit $n $count ++; } } } # tidy the ends of the strings for $s ($string1, $string2) { $s =~ s|, (\d+), $| and $1|; } # say the answers say qq[Output: $count]; say qq[The divisors of $m are $string1]; if ($string2) { say qq[There are only $count divisors with last digit $n: $string2]; } else { say qq[There are no divisors with last digit $n]; } }
Input: $m = 24, $n = 2 Output: 2 The divisors of 24 are 1, 2, 3, 4, 6, 8, 12 and 24 There are only 2 divisors with last digit 2: 2 and 12 Input: $m = 30, $n = 5 Output: 2 The divisors of 30 are 1, 2, 3, 5, 6, 10, 15 and 30 There are only 2 divisors with last digit 5: 5 and 15 Input: $m = 24, $n = 7 Output: 0 The divisors of 24 are 1, 2, 3, 4, 6, 8, 12 and 24 There are no divisors with last digit 7 Input: $m = 37, $n = 0 Output: 0 The divisors of 37 are 1 and 37 There are no divisors with last digit 0 Input: $m = 45, $n = 5 Output: 3 The divisors of 45 are 1, 3, 5, 9, 15 and 45 There are only 3 divisors with last digit 5: 5, 15 and 45 Input: $m = 1048575, $n = 5 Output: 32 The divisors of 1048575 are 1, 3, 5, 11, 15, 25, 31, 33, 41, 55, 75, 93, 123, 155, 165, 205, 275, 341, 451, 465, 615, 775, 825, 1023, 1025, 1271, 1353, 1705, 2255, 2325, 3075, 3813, 5115, 6355, 6765, 8525, 11275, 13981, 19065, 25575, 31775, 33825, 41943, 69905, 95325, 209715, 349525 and 1048575 There are only 32 divisors with last digit 5: 5, 15, 25, 55, 75, 155, 165, 205, 275, 465, 615, 775, 825, 1025, 1705, 2255, 2325, 3075, 5115, 6355, 6765, 8525, 11275, 19065, 25575, 31775, 33825, 69905, 95325, 209715, 349525 and 1048575 Input: $m = 1048576, $n = 2 Output: 5 The divisors of 1048576 are 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288 and 1048576 There are only 5 divisors with last digit 2: 2, 32, 512, 8192 and 131072
Any content of this website which has been created by Peter Campbell Smith is in the public domain