# Perl Weekly Challenge 91

I finally got some time between my day job and Advent of Code to tackle this week’s Perl Weekly Challenge. Pretty easy stuff this week; hope the difficulty ramps up soon!

You are given a positive number `\$N`.

Write a script to count number and display as you read it.

### Example 1

``````Input: \$N = 1122234  # ("two 1 three 2 one 3 one 4")
Output: 21321314
``````

### Example 2

``````Input: \$N = 2333445  # ("one 2 three 3 two 4 one 5")
Output: 12332415
``````

### Example 3

``````Input: \$N = 12345  # ("one 1 one 2 one 3 one 4 one 5")
Output: 1112131415
``````

### Solution

See below for explanation and any implementation-specific comments.

``````sub challenge(\$N) {
my @digits = \$N.comb.map(*.Int);

my (\$current-num, \$current-count);
my \$first = True;
my @output;
for @digits.kv -> \$index, \$digit {
# If this is the first round, just set our variables and continue
if \$first {
\$first = False;
\$current-num = \$digit;
\$current-count = 1;
next;
}

# Otherwise, just keep track of our current digit/count
if \$digit == \$current-num {
\$current-count += 1;
} else {
@output.push(\$current-count);
@output.push(\$current-num);
\$current-num = \$digit;
\$current-count = 1;
}

# We need this to push the last number on, or it will get lost
if \$index == @digits.elems - 1 {
@output.push(\$current-count);
@output.push(\$current-num);
}
}

@output.join;
}

multi sub MAIN(\$N where \$N ~~ Int && \$N > 0) {
say challenge(\$N);
}

multi sub MAIN(:\$test) {
use Test;

my @tests = (
(1122234, 21321314),
(2333445, 12332415),
(12345, 1112131415)
);

for @tests -> @test {
is(challenge(@test), @test);
}

done-testing;
}
``````

This program runs as such:

``````\$ raku ch-1.raku 1122234
21321314

\$ raku ch-1.raku --test
ok 1 -
ok 2 -
ok 3 -
1..3
``````

### Explanation

You can see this week I started adding tests for my scripts (utilized by passing in the `--test` flag), so all the logic lives in `challenge`.

The logic is pretty easy – as we iterate from left-to-right we keep track of the current digit and its count. If we encounter a new digit, we push the old `\$current-digit` and old `\$current-count` onto `@output` and reset our variables. The only special handling is around the first digit (when there is no `\$current-digit`), and the last digit (since we need to store the last digit and count before exiting).

You are given an array of positive numbers `@N`, where value at each index determines how far you are allowed to jump further.

Write a script to decide if you can jump to the last index. Print 1 if you are able to reach the last index otherwise 0.

### Solution

See below for explanation and any implementation-specific comments.

``````subset PositiveInt of Int where { \$_ >= 0 }

sub challenge(@N) {
my Int \$pointer = 0;
my Bool \$reached-the-end;

loop {
given \$pointer {
when * < @N.elems - 1  {
my \$value = @N[\$pointer];
if \$value == 0 {
\$reached-the-end = False;
last;
} else {
\$pointer += @N[\$pointer]
}
}
when * == @N.elems - 1 {
\$reached-the-end = True;
last;
}
when * > @N.elems - 1  {
\$reached-the-end = False;
last;
}
}
}

\$reached-the-end.Int;
}

multi sub MAIN(*@N where all(@N) ~~ PositiveInt) {
say challenge(@N);
}

multi sub MAIN(:\$test) {
use Test;

my @tests = (
((1, 2, 1, 2), 1),
((2, 1, 1, 0, 2), 0)
);

for @tests -> @test {
is(challenge(@test), @test);
}

done-testing;
}
``````

This program runs as such:

``````\$ raku ch-2.raku 1 2 1 2
1

\$ raku ch-2.raku --test
ok 1 -
ok 2 -
1..2
``````

### Explanation

We set the `\$pointer` to start at index 0 and enter an infinite loop. If we are not at the end we have to check if the current value is `0`. If it is, we have gone as far as we can and need to exit (`last`), otherwise keep going. If we are at at the end, exit and mark` \$reached-the-end` as `True`. If we have passed the end, exit and mark `\$reached-the-end` as `False`. Since the problem asks for an integer output, we have to cast our boolean to an integer before returning.

## Final Thoughts

Nothing ground breaking this week. However, we did get to explore one of the cooler features of Raku for Advent of Code day 18. Give it a read!

Tags:

Categories:

Updated: