## TABLE OF CONTENTS

### 1. HEADLINES

### 2. YouTube WEEKLY

### 3. TASK #1: Smallest Positive Number

### 4. TASK #2: Count Candies

## HEADLINES

This week, both tasks were comparatively easier than last week. I followed the rule, doing **Perl** first then translating the same into **Raku**. But while working on **Raku**, I got fresh ideas. I then went back to my **Perl** and re-worked the logic. One day, I would like to do **Raku** first then translate it into **Perl**.

## YouTube WEEKLY

Sorry, I couldn’t make video for this week tasks.

However, you can take a look at my past week videos by visiting my **YouTube Channel**.

Last but not the least, I would to love hear your **views/opinions** with regard to anything I do.

Please get in touch with me by email: mohammad.anwar@yahoo.com.

Let me share my solutions to the **The Weekly Challenge - 080**.

## TASK #1 › Smallest Positive Number

#### Submitted by **Mohammad S Anwar**

You are given unsorted list of integers `@N`

.

Write a script to find out the smallest positive number missing.

The following `sub smallest_positive_number()`

does the main job by stripping negative numbers and sorting in the end. If nothing left after this operation then return 1 as the smallest positive number. For all others, loop through 1 and highest positive number in the array.

```
sub smallest_positive_number {
my ($arrayref) = @_;
my @positive_numbers = sort(grep $_ > 0, @$arrayref);
return 1 unless (@positive_numbers);
my $i = 0;
for my $n (1 .. $positive_numbers[-1]) {
return $n if ($n < $positive_numbers[$i++]);
}
return ++$positive_numbers[-1];
}
```

The helper `sub get_list()`

takes the string and converts into arrayref.

```
sub get_list {
my ($l) = @_;
die "ERROR: Missing list.\n" unless defined $l;
die "ERROR: Invalid list [$l].\n" unless ($l =~ /^[\-?\d\,?\s?]+$/);
$l =~ s/\s//g;
return [ split /\,/, $l ];
}
```

With the power of **Raku**, just one `sub smallest-positive-number()`

is enough to solve the task. If you notice the similarity between **Raku** and **Perl** is because I copied the logic from **Raku** version.

```
sub smallest-positive-number(@n where .all ~~ Int --> Int) {
my @positive-numbers = @n.sort.grep: { $_ > 0 };
return 1 unless @positive-numbers.elems;
my Int $i = 0;
(1 .. @positive-numbers.tail).map: -> $n {
return $n if $n < @positive-numbers[$i++]
};
return ++@positive-numbers.tail;
}
```

One-liner **Perl** solution with the helper subroutine.

```
use strict;
use warnings;
my $N = $ARGV[0] || "2, 3, 7, 6, 8, -1, -10, 15";
printf("%s => %d\n", $N, smallest_positive_number(get_list($N)));
```

Even cleaner version in **Raku** as below.

```
use v6.d;
sub MAIN(:@N where .all ~~ Int = (2, 3, 7, 6, 8, -1, -10, 15)) {
say smallest-positive-number(@N);
}
```

Plenty of unit test to make it complete solution.

```
use strict;
use warnings;
use Test::More;
# examples from the task
is (smallest_positive_number([5, 2, -2, 0]), 1, "testing (5, 2, -2, 0)");
is (smallest_positive_number([1, 8, -1]), 2, "testing (1, 8, -1)");
is (smallest_positive_number([2, 0, -1]), 1, "testing (2, 0, -1)");
# some other test cases
is (smallest_positive_number([1, 2, 0]), 3, "testing (1, 2, 0)");
is (smallest_positive_number([-8, -7, -6]), 1, "testing (-8, -7, -6)");
is (smallest_positive_number([3, 4, -1, 1]), 2, "testing (3, 4, -1, 1)");
is (smallest_positive_number([2, 3, 7, 6, 8, -1, -10, 15]), 1, "testing (2, 3, 7, 6, 8, -1, -10, 15)");
done_testing;
```

Same unit test in **Raku**.

```
use Test;
# examples from the task
is smallest-positive-number((5, 2, -2, 0)), 1,
"testing (5, 2, -2, 0)";
is smallest-positive-number((1, 8, -1)), 2,
"testing (1, 8, -1)";
is smallest-positive-number((2, 0, -1)), 1,
"testing (2, 0, -1)";
# some other test cases
is smallest-positive-number((1, 2, 0)), 3,
"testing (1, 2, 0)";
is smallest-positive-number((-8, -7, -6)), 1,
"testing (-8, -7, -6)";
is smallest-positive-number((3, 4, -1, 1)), 2,
"testing (3, 4, -1, 1)";
is smallest-positive-number((2, 3, 7, 6, 8, -1, -10, 15)), 1,
"testing (2, 3, 7, 6, 8, -1, -10, 15)";
done-testing;
```

## TASK #2 › Count Candies

#### Submitted by **Mohammad S Anwar**

You are given rankings of @N candidates.

Write a script to find out the total candies needed for all candidates. You are asked to follow the rules below:

#### a) You must given at least one candy to each candidate.

#### b) Candidate with higher ranking get more candies than their mmediate neighbors on either side.

I enjoyed working on this task. For the first time, I had more than one way of dealing with the task. I picked the solution easy to read.

```
sub count_candies {
my ($rankings) = @_;
my $l2r = [];
my $r2l = [];
push @$l2r, 1 for @$rankings;
push @$r2l, 1 for @$rankings;
my $i = 1;
while ($i <= $#$rankings) {
$l2r->[$i] = $l2r->[$i - 1] + 1
if ($rankings->[$i] > $rankings->[$i - 1]);
$i++
}
my $j = $#$rankings - 1;
while ($j >= 0) {
$r2l->[$j] = $r2l->[$j + 1] + 1
if ($rankings->[$j] > $rankings->[$j + 1]);
$j--;
}
my $count = 0;
$count += max($l2r->[$_], $r2l->[$_]) for (0 .. $#$rankings);
return $count;
}
```

Helper `sub get_rankings()`

to convert the command line input into arrayref.

```
sub get_rankings {
my ($c) = @_;
die "ERROR: Missing rankings.\n" unless defined $c;
die "ERROR: Invalid rankings [$c].\n" unless ($c =~ /^[\d\,?\s?]+$/);
$c =~ s/\s//g;
return [ split /\,/, $c ];
}
```

This is plain translation of **Perl** version.

```
sub count-candies(@rankings
where @rankings.elems > 1 &&
all(@rankings) ~~ PositiveInt --> Int) {
my @l2r = Empty;
my @r2l = Empty;
@l2r.push: 1 for @rankings;
@r2l.push: 1 for @rankings;
my Int $i = 1;
while $i < @rankings.elems {
@l2r[$i] = @l2r[$i - 1] + 1
if @rankings[$i] > @rankings[$i - 1];
$i++;
}
my Int $j = @rankings.elems - 2;
while $j >= 0 {
@r2l[$j] = @r2l[$j + 1] + 1
if @rankings[$j] > @rankings[$j + 1];
$j--;
}
my Int $count = 0;
$count += (@l2r[$_], @r2l[$_]).max for 0 .. @rankings.elems - 1;
return $count;
}
```

Time to get the task done in **Perl**.

```
use strict;
use warnings;
use List::Util qw(max);
my $C = $ARGV[0] || "1, 5, 2, 1";
printf("Total candies: %d\n", count_candies(get_rankings($C)));
```

Followed by **Raku** version.

```
use v6.d;
subset PositiveInt of Int where * > 0;
sub MAIN(*@N where @N.elems > 1 && all(@N) ~~ PositiveInt) {
say "Total candies: " ~ count-candies(@N);
}
```

In the end some basic unit test in **Perl**.

```
use strict;
use warnings;
use Test::More;
use List::Util qw(max);
is( count_candies([1, 2]), 3, "testing: [1, 2]");
is( count_candies([1, 2, 2]), 4, "testing: [1, 2, 2]");
is( count_candies([1, 5, 2, 1]), 7, "testing: [1, 5, 2, 1]");
done_testing;
```

along with unit test in **Raku**.

```
use Test;
subset PositiveInt of Int where * > 0;
is count-candies((1, 2)), 3, "testing: (1, 2)";
is count-candies((1, 2, 2)), 4, "testing: (1, 2, 2)";
is count-candies((1, 5, 2, 1)), 7, "testing: (1, 5, 2, 1)";
done-testing;
```

That’s it for this week. Speak to you soon.