TASK2: https://theweeklychallenge.org/blog/perl-weekly-challenge-350/#TASK2
Looks like the consensus on how to approach this would be to "split, sort, join" to generate keys for finding pair pals. Further, as smarter guys explained, using modulo arithmetic voodoo, a lot of unfriendly numbers (which can't have any pals anyway) should simply be skipped; and, of those that remain, it's pointless to ask some of the witnesses about, i.e skip these witnesses, too. So, my subroutine to solve the problem is:
sub pwc {
my ( $from, $to, $target ) = @_;
use integer;
my @witnesses = ([ 4, 7 ], [ 2 .. 9 ]);
my ( %pairs, $j );
for ( my $i = ( $from + 2 ) / 3 * 3; $i <= $to; $i += 3 ) {
my $i_key = join '', sort split '', $i;
my $k = $i % 9 ? 0 : 1;
for ( @{ $witnesses[ $k ]}) {
last if length( $j = $i * $_ ) != length( $i );
$pairs{ $i }{ $j } = $_
unless $i_key ne join '', sort split '', $j
}
for ( @{ $witnesses[ $k ]}) {
last if length( $j = $i / $_ ) != length( $i );
$pairs{ $i }{ $j } = -$_
unless $i % $_
|| exists $pairs{ $j } &&
exists $pairs{ $j }{ $i }
|| $i_key ne join '', sort split '', $j
}
}
return scalar grep { %$_ >= $target } values %pairs
}
However, even though some solutions mention "speed", I haven't seen optimizations which follow. First, if using CPAN modules is OK (and why not), almost exactly twice as fast is to sort in-place instead:
|