Perl Weekly Challenge 136: not too hard

It is sad that, after more than two years of me doing Raku, I still don’t have any production code project to work on. Therefore, in order to keep my coding and Raku-ing (is that a term?) knowdledge, I try to solve every Perl Weekly Challenge tasks.

In the following, the assigned tasks for Challenge 136.

Linux Day 2021

I gave a brief and quick presentation about Raku and how I feel about it. The talk is in italian, and can be seen as an extracted and cut video on Odysee.



PWC 136 - Task 1

The first task was a one-liner for me: find out if, given two numbers, their Greatest Common Divisor is a power of 2.

sub MAIN( Int $m where { $m > 0 }, Int $n where { $n > 0 } ) {
    ( [gcd] $m, $n ) %% 2 ?? '1'.say !! '0'.say;
}



It work as follows:
  • it computes the Greatest Common Divisor by using the gcd built-in operator;
  • is compares the result with the %% operator to see if it is a multiple of 2, that means also if it is a positive power of 2;
  • the ternary operatory prints out 1 or 0 depending respectively on success or failure.

PWC 136 - Task 2

The second task involved somehow the Fibonacci’s serie and its sum: given a positive number, find out all available combinations of a trimmed Fibonacci’s series in order to match exactly the given sum.

sub MAIN( Int $n where { $n > 1 } ) {
    my @fibonacci;
    @fibonacci.push: 1, 1;
    my %solutions;

    # compute a reduced fibonacci sequence up to the sum of the number given
    @fibonacci.push: @fibonacci[ * - 1 ] + @fibonacci[ * - 2 ]  while $n > ( @fibonacci[ * - 1] + @fibonacci[ * - 2 ]);


    # iterate over all the available numbers, and compute the sum
    # and if the sum does match, add the array to the hash of solutions
    # with a stringified key representation
    %solutions{ $_.join( ' + ') } = $_ if ( ( [+] $_ ) == $n ) for @fibonacci.combinations.unique;

    # print the number of keys
    say %solutions.keys.elems;
    # and print all the sums
    .join( " + " ).say for %solutions.values;

}




First of all, I compute a reduced @fibonacci array of numbers: numbers are pushed to the array only if their Fibonacci sum clause does not result greater than the given number.
Then I build an hash %solutions indexed with a string representation of the current Fibonacci’s sequence of numbers, and with a value of a subset of the Fibonacci’s array if the sum of such array is the searched for value.
Using an hash guarantees that I’m not going to find out duplicated sequences, and therefore it does suffice to print out the number of keys and, optionally, the human readable sums.
As an example of output:

 % raku ch-2.p6 16
4
3 + 5 + 8
1 + 2 + 5 + 8
1 + 2 + 13
3 + 13



In the above there are 4 solutions, that are displayed as expanded sums in the subsequent lines.


## Another, shorter, implementation of the second task

After lunch, I realized there could be a shorter implementation of this that uses the `grep` filter.

<br/>
<br/>

``` raku
my @fibonacci = 1, 1, * + * ... * > $n;
my @solutions = @fibonacci.unique.combinations.grep( *.sum == $n );
@solutions.elems.say;
.join( ' + ' ).say for @solutions;


First, the @fibonacci is computed by means of a sequence, and is stopped as soon as we find the first element greater than the expected value.
Then, I do grep considering the sum of the array of combinations and look for a value as expected. The rest is the same printing as in the above piece of code.

The article Perl Weekly Challenge 136: not too hard has been posted by Luca Ferrari on October 25, 2021