ETOOBUSY 🚀 minimal blogging for the impatient
PWC142 - Divisor Last Digit
TL;DR
Here we are with TASK #1 from The Weekly Challenge #142. Enjoy!
The challenge
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.
The questions
I guess that $n
might be… different, right? From how it’s used, it
seems that it should be a single digit… and that it should also be
allowed to be 0
. Anyway, I’ll enforce only that it’s a single digit
(but only in Raku).
The solution
Well… let’s do this the boring way. We build a function to find out
all divisors for the input $m
, then filter it and count the result.
#!/usr/bin/env raku
use v6;
subset PosInt of Int where * > 0;
subset PosDigit of Int where 0 < * <= 9;
sub divisors-for (PosInt:D $n) {
(1 .. $n.sqrt.Int).grep({$n %% $_}).map({$_, ($n / $_).Int})
.flat.Set.keys;
}
sub MAIN (PosInt:D $m = 24, PosDigit:D $n = 2) {
divisors-for($m).grep({.substr(*-1, 1) == $n}).elems.put;
}
The iteration goes up to the square root of the input because each
divisor $k$ will also give its counterpart $\frac{n}{k}$. The grep
filters only the items that actually divide $n
(using operator %%
,
yay!), then the map
gives out the number itself and its counterpart.
Here we might have two problems, though. First, the output of the map
is pairs of numbers, so we have to flat
to get a plain list out.
Additionally, the square root of perfect squares would pop up twice, so
we need to make sure to eliminate the duplicate. So we pass the list
through a Set
and then take the keys.
One last thing is… that 5
and 25/5
are not the same thing. The
first is an Int
, the second a Rat
! So we need to turn the division
into an Int
.
Here’s a Perl translation. Somehow it seems much simpler!
#!/usr/bin/env perl
use v5.24;
use warnings;
use experimental 'signatures';
no warnings 'experimental::signatures';
sub divisors_for ($n) {
keys %{{map { $_ => 1, int($n / $_) => 1 } grep { !($n % $_) }
1 .. sqrt($n)}};
}
my $m = shift // 24;
my $n = shift // 2;
say scalar [grep { substr($_, -1, 1) == $n } divisors_for($m)]->@*;
OK, enough for today… stay safe!