I’ve been doing the Perl Weekly
Challenges. The
latest
was about generating number sequences.
Part 1 is to list the attractive numbers (having a list of prime
factors that itself contains a prime number of entries) that lie
between 1 and 50 inclusive. I'm using my private set of rules for
these challenges, which is that it's OK to use Perl5 modules as long
as they solve only part of the problem (having a solution that's just
a function call is no fun), but Perl6 should work with what's
available in the language core (since it's so much larger).
So for Perl5:
use Math::Prime::Util qw(factor is_prime);
foreach my $c (1..50) {
if (is_prime(scalar factor($c))) {
print "$c\n";
}
}
Meanwhile in Perl6 I build a list of relevant primes (and a hash of it
so that I can look things up in it quickly), then factorise by trial
modulo (inefficient, but with numbers this small it really doesn't
matter).
my $top=50;
my @factors=grep {is-prime($_)}, (1..$top);
my %pc=map {$_ => 1}, @factors;
for (1..$top) -> $c {
my $cc=$c;
my $cn=0;
my @ff=@factors;
while ($cc != 1 && !(%pc{$c}:exists)) {
my $l=@ff[0];
while ($cc % @ff[0] == 0) {
$cn++;
$cc /= @ff[0];
}
shift @ff;
}
if (%pc{$c}:exists) {
$cn++;
}
if (%pc{$cn}:exists) {
say $c;
}
}
Part 2 asks for the first twenty Leonardo numbers (calculated like Fibonacci
numbers after the first two, but adding 1 each time, so 1, 1, 3, 5, 9,
…).
my @stack;
foreach my $i (0..19) {
if ($i<2) {
push @stack,1;
} else {
push @stack,1+$stack[-1]+$stack[-2];
shift @stack;
}
print $stack[-1],"\n";
}
I don't really need that shift @stack
, but putting it in allows the
number limit to be set as high as I like without risking running out
of memory. Perl6 in this case works the same way, but using
@stack[@stack.end]
rather than $stack[-1]
.
Comments on this post are now closed. If you have particular grounds for adding a late comment, comment on a more recent post quoting the URL of this one.