# Perl Weekly Challenge 112: Climbing the canonical path!

One way to let me improve my knowledge about Raku (aka Perl 6) is to implement programs in it. Unluckily, I don’t have any production code to implement in Raku yet (sob!). So, why not try solving the Perl Weekly Challenge tasks?In the following, the assigned tasks for Challenge 112.

## PWC 112 - Task 1

The first task was about writing a script to make a given filesystem path*canonical*, that is removing all the spurious data such as

`..`

, `.`

, replicated slashes, and so on.
Raku

`IO::Path`

already has a way to make a path canonical, but it does it without trimming out `..`

, while the task required to interpret such characters in making the path *smart*. For example:

`/a/b/../d`

should resolve in `/a/d`

because `..`

makes the system to go up one level, so removing the `b`

descending.
Therefore, I decided to implement it using a

`split`

approach:
- I do split the path according to its separator;
- add every part of the path to an array if and only if it is not empty (meaning a multiple slash has occurred) and is not
`.`

, meaning nothing has to be done; - in the case the part of the path is
`..`

I have to trim out the last value of the already computed array of parts, that is how I go up one level.

```
sub MAIN( Str :$path ) {
my @results;
for $path.split( '/' ) {
next if ! $_ || $_ ~~ '.';
@results.push: $_ if ( $_ !~~ '..' );
@results = @results[ 0 .. * - 2 ] if $_ ~~ '..';
}
('/' ~ @results.join( '/' )).say;
}
```

Please note I’ve added an extra leading slash in front of the

`say`

line, so that the path is outputted as absolute.
## PWC 112 - Task 2

The second task was about finding out the sum of`1`

and `2`

that can lead to a specific value, aslo known as *climbing stairs*problem.

I’ve implemented in a very

*unefficient*way:

- I create an array of all possible
`1`

and`2`

that can lead to the sum of the given number; - I do iterate on every possible iteration of such an array, and see how many elements I need to get the sum;
- I print out the resulting arrays only using
`unique`

values.

Therefore it results as follows:

```
sub MAIN( Int $top where { $top > 1 } ) {
my @haystack = (1 xx $top, 2 xx $top / 2).flat;
my @solutions;
# get all possible combinations
for @haystack.permutations {
# check every sub-array that gives me the sum
for 0 ..^ $_.elems -> $index {
@solutions.push: $_[ 0 .. $index ] if $_[ 0 .. $index ].sum == $top;
}
}
# print only unique values
say @solutions.unique: as => { .Str };
}
```

This is really expensive, since it can quickly require a lot of permutations to compute. Therefore I decided to follow a different approach:

- I build the very first solution, that is made by only
`1`

up to the`$top`

value; - I then start using the solution as a string of
`1`

s and substitute every`11`

with a`2`

; - I do compute all the possible permutations of every
`2`

in the list.

Therefore the program is:

```
sub MAIN( Int $top where { $top > 1 } ) {
my @solutions;
@solutions.push: 1 xx $top;
my $current-solution = 1 x $top;
while ( $current-solution ~~ / 1 ** 2 / ) {
$current-solution ~~ s/ 1 ** 2 / 2 /;
$current-solution = $current-solution.split( ' ', :skip-empty ).join( '' );
@solutions.push: $_ for $current-solution.split( '', :skip-empty ).permutations.unique( as => { .Str.trim } );
}
for @solutions -> @current-solution {
say "\nPossible solution:";
"%d step%s ".sprintf( $_, $_ > 1 ?? 's' !! '' ).print if $_ > 0 for @current-solution;
}
say "";
}
```

There is some machinery to avoid empty spaces here and there, and also I placed the

`unique`

ness of the solutions up to the permutation level, so that the final array `@solutions`

is already made by unique lists.
The printing also evolved so that I can correctly print

`step`

or `steps`

. The result is:
```
% raku ch-2.p6 5
Possible solution:
1 step 1 step 1 step 1 step 1 step
Possible solution:
2 steps 1 step 1 step 1 step
Possible solution:
1 step 2 steps 1 step 1 step
Possible solution:
1 step 1 step 2 steps 1 step
Possible solution:
1 step 1 step 1 step 2 steps
Possible solution:
2 steps 2 steps 1 step
Possible solution:
2 steps 1 step 2 steps
Possible solution:
1 step 2 steps 2 steps
```

And this is it.