In this post, there’re my solutions to the tasks of Week 3 of the Perl Weekly Challenge.
Task 1
Generate a list of Regular numbers, which are the numbers, whose prime factors do not exceed 5.
In my book Using Raku, there is an example of computing prime factors of a number. Actually, that solution can be simplified to the following code, as we don’t need to keep track of repeated factors:
my $max = 20; my @prime = grep *.is-prime, ^$max; for 1..$max -> $n { say "Prime factor(s) of $n: " ~ grep {$n %% $_}, @prime; }
For the numbers below 20, we have the following result:
$ raku prime-factors.raku Prime factor(s) of 1: Prime factor(s) of 2: 2 Prime factor(s) of 3: 3 Prime factor(s) of 4: 2 Prime factor(s) of 5: 5 Prime factor(s) of 6: 2 3 Prime factor(s) of 7: 7 Prime factor(s) of 8: 2 Prime factor(s) of 9: 3 Prime factor(s) of 10: 2 5 Prime factor(s) of 11: 11 Prime factor(s) of 12: 2 3 Prime factor(s) of 13: 13 Prime factor(s) of 14: 2 7 Prime factor(s) of 15: 3 5 Prime factor(s) of 16: 2 Prime factor(s) of 17: 17 Prime factor(s) of 18: 2 3 Prime factor(s) of 19: 19 Prime factor(s) of 20: 2 5
Now let’s use this program as a base for solving the task. If the number is Regular, then all of its prime factors are below and including 5, which you can express as:
all(map * <= 5, grep {$n %% $_}, @prime)
Finally, assemble the pieces together:
my $max = 60; my @prime = grep *.is-prime, ^$max; for 1..$max -> $n { say $n if all(map * <= 5, grep {$n %% $_}, @prime); }
You get these numbers in the output:
2 3 4 5 6 8 9 10 12 15 16 18 20 24 25 27 30 32 36 40 45 48 50 54 60
Run the program with different maximum values and compare the result with the sequence listed at oeis.org/A051037.
Task 2
Print the Pascal triangle with the given number of rows.
This task is directly solved in the same book, please find a solution on my site.
Let me add some code to print the triangle as a symmetrical shape:
my $rows = 10; my @row = 1; my @lines = gather { take 1; for 1 ..^ $rows { @row = (|@row, 0) >>+<< (0, |@row); take @row.join(' '); } } my $width = @lines[*-1].chars; .say for map({(' ' x ($width - $_.chars) / 2) ~ $_}, @lines);
This is the result for the requested 10 rows:
$ raku ch-2.raku 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 1 6 15 20 15 6 1 1 7 21 35 35 21 7 1 1 8 28 56 70 56 28 8 1 1 9 36 84 126 126 84 36 9 1
Find the source files of today’s solutions at my GitHub repository.
→ GitHub repository
→ Navigation to the Raku challenges post series