More Raku challenges

Task 1: Find the first 20 so-called Gapful numbers. Task 2: Print all palindromic ddmmyyyy dates between 2000 and 3000. Task 3: Find the first multiple of the given number, which only contains digits 0 and 1.

Week 47, issue 2

Task: find the first 20 so-called Gapful numbers, which are the numbers that are divisible by the number formed by their first and the last digit. E.g., 132 passes the filter, as 132 / 12 divides without remainder.

The whole solution:

my $found = 0;
for 100 ... * -> $n {
    my $m = [~] $n.comb[0, *-1];
    
    next if $n % $m;
    last if $found++ == 20;

    say $n;
}

Maybe the only thing to comment here is the line with [~] $n.comb[0, *-1]. It does at least four things: converts the number into a string, splits it into characters, takes the first and the last elements of it and then concatenates the two characters.

Week 48, issue 2

Task: Find and print all palindromic ddmmyyyy dates between 2000 and 3000.

To loop over the date range, we can use a couple of Date objects and the sequence operator:

for Date.new(year => 2000) ..^ Date.new(year => 3000) -> $date {
    . . .
}

To find if a string is a palindrome, use the flip method. The last bit to code is to print the date in the given format.

for Date.new(year => 2000) ..^ Date.new(year => 3000) -> $date {
    my $ddmmyyyy = 
        sprintf '%02d%02d%d', .day, .month, .year given $date;
    say $ddmmyyyy if $ddmmyyyy eq $ddmmyyyy.flip;
}

That’s it. The program prints 36 different dates, here are the first of them:

10022001
20022002
01022010
11022011
21022012
02022020
12022021
22022022
03022030
13022031
23022032
04022040
. . .

Week 49, issue 1

Task: Find the first multiple of the given number, which only contains digits 0 and 1.

This is a good task to use sequences. For the given number $n, the sequence of its multiples can be generated as $n, 2 * $n ... *. Lazy evaluation allows us not to worry about computing extra items.

Let’s simply find the first value that matches the condition expressed via a regex:

my $n = +@*ARGS[0];

say ($n, 2 * $n ... *).first: * ~~ /^<[01]>+$/;

Notice that it is important to convert the input string to an integer, thus you should not omit the prefix +. Instead, explicit conversion can be done:

my $n = @*ARGS[0].Int;

For the input 55, this program prints 110 as expected. Run it for different numbers:

$ raku ch-049-1.raku 55
110

$ raku ch-049-1.raku 14
10010

$ raku ch-049-1.raku 7
1001

$ raku ch-049-1.raku 143
1001

$ raku ch-049-1.raku 71
10011

Here’s a link to the GitHub repository, where you can find the source codes of today’s solutions.

Navigation to the Raku challenges post series

2 thoughts on “More Raku challenges”

  1. Re week 84, task 2: In newer versions of Raku, the `Date` class also has a `dd-mm-yyyy` method, which takes an optional delimiter (default: “-“). So you could write:

    my $ddmmyyyy = $date.dd-mm-yyyy(“”);

    Also, in your example, you appear to have switched `.month` and `.day`, so you are in fact testing for `mmddyyyy` rather than `ddmmyyyy`.

Leave a Reply

Your email address will not be published. Required fields are marked *