PERL WEEKLY CHALLENGE – 041

This is my 11th week participating into the weekly challenge.


Easy Challenge

Write a script to display attractive number between 1 and 50.

A number is an attractive number if the number of its prime factors is also prime number.

The number 20 is an attractive number, whose prime factors are 2, 2 and 5. The total prime factors is 3 which is also a prime number.

This is just factoring a number is checking if it’s prime.

Perl has a good module for this and will do all the heavy lifting for this task
https://metacpan.org/pod/Math::Prime::Util

In Raku, the is-prime method is already built in, but not the factoring. I googled factoring numbers in Raku because I was a bit tired and didn’t really want to think of an algorithm so I blatantly copied the first piece of code that looked like it would work. Did some minor tweaks to get it to work in a function.

Factorization code copied from:
https://andrewshitov.com/2019/09/09/finding-prime-factors-using-perl-6/

Perl 5 solution

#!/usr/bin/perl
# Test: ./ch1.pl
use strict;
use warnings;
use Math::Prime::Util qw /factor is_prime/;
use feature qw /say/;

for my $i (1..50) {
	my @factors = factor($i);
	say $i if (is_prime(scalar(@factors)));
}

Output

4
6
8
9
10
12
14
15
18
20
21
22
25
26
27
28
30
32
33
34
35
38
39
42
44
45
46
48
49
50

Raku solution

# Test: perl6 ch1.p6
use v6.d;

sub MAIN() {
	for (1..50) -> $i {
		my @factors = factors($i);
		say $i if @factors.elems.is-prime;
	}
}

# This was blatantly copied
sub factors (Int $n) {
	my @list;
	my @prime = grep {.is-prime}, 1..*;
	my $pos = 0;
	my $check = $n;

	while $check > 1 {
		my $factor = @prime[$pos];
		$pos++;
		next unless $check %% $factor;

		$pos = 0;
		$check /= $factor;
		push @list, $factor;
	}

	return @list;
}

Output

4
6
8
9
10
12
14
15
18
20
21
22
25
26
27
28
30
32
33
34
35
38
39
42
44
45
46
48
49
50

Hard Challenge

Write a script to display first 20 Leonardo Numbers. Please checkout wiki page for more information.

For example:

L(0) = 1
L(1) = 1
L(2) = L(0) + L(1) + 1 = 3
L(3) = L(1) + L(2) + 1 = 5
and so on.


Leonardo numbers look surprisingly similar to Fibonacci numbers.

In perl 5 we just use recursion to calculate Leonardo’s number just like we did when we first learned about Fibonacci numbers in Perl or any other computer science course.

In Raku, I used the powerful sequence operator and generated a lazy infinite list.


Perl 5 solution

#!/usr/bin/perl
# test: ./ch2.pl
use strict;
use warnings;
use feature qw /say/;

for my $i (1..20) {
	say "L($i) = " . leonardo($i);
}

# Leonardo
sub leonardo {
	my $n = shift;
	return 1 if ($n == 0 or $n == 1);

	# Recursive
	return (
		leonardo($n-1) +  # l(n-1)
		leonardo($n-2) +  # l(n-2)
		1                 # 1
	);
}

Output

L(1) = 1
L(2) = 3
L(3) = 5
L(4) = 9
L(5) = 15
L(6) = 25
L(7) = 41
L(8) = 67
L(9) = 109
L(10) = 177
L(11) = 287
L(12) = 465
L(13) = 753
L(14) = 1219
L(15) = 1973
L(16) = 3193
L(17) = 5167
L(18) = 8361
L(19) = 13529
L(20) = 21891

Raku solution

# Test: perl6 ./ch2.p6
use v6.d;

sub MAIN () {
	my @leonardo = 1, 1, * + * + 1 ... *;
	say "L($_) = " ~ @leonardo[$_]
		for (1 .. 20);
}

Output

L(1) = 1
L(2) = 3
L(3) = 5
L(4) = 9
L(5) = 15
L(6) = 25
L(7) = 41
L(8) = 67
L(9) = 109
L(10) = 177
L(11) = 287
L(12) = 465
L(13) = 753
L(14) = 1219
L(15) = 1973
L(16) = 3193
L(17) = 5167
L(18) = 8361
L(19) = 13529
L(20) = 21891

One thought on “PERL WEEKLY CHALLENGE – 041

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s