# PERL WEEKLY CHALLENGE – 042

This is my 12th week participating into the weekly challenge.

## Easy Challenge

Octal Number System
Write a script to print decimal number 0 to 50 in Octal Number System.

For example:

Decimal 0 = Octal 0
Decimal 1 = Octal 1
Decimal 2 = Octal 2
Decimal 3 = Octal 3
Decimal 4 = Octal 4
Decimal 5 = Octal 5
Decimal 6 = Octal 6
Decimal 7 = Octal 7
Decimal 8 = Octal 10
and so on.

In perl 5 and Raku we can display octals using printf or sprintf.

#### Perl 5 solution

``````#!/usr/bin/perl
# Test: ./ch1.pl
use strict;
use warnings;
use feature qw /say/;

for my \$i (1..50) {
say 'Decimal '  . \$i .
' = Octal ' . to_octal(\$i);
}

sub to_octal {
return sprintf('%o', shift);
}
``````

Output

``````Decimal 1 = Octal 1
Decimal 2 = Octal 2
Decimal 3 = Octal 3
Decimal 4 = Octal 4
Decimal 5 = Octal 5
Decimal 6 = Octal 6
Decimal 7 = Octal 7
Decimal 8 = Octal 10
Decimal 9 = Octal 11
Decimal 10 = Octal 12
Decimal 11 = Octal 13
Decimal 12 = Octal 14
Decimal 13 = Octal 15
Decimal 14 = Octal 16
Decimal 15 = Octal 17
Decimal 16 = Octal 20
Decimal 17 = Octal 21
Decimal 18 = Octal 22
Decimal 19 = Octal 23
Decimal 20 = Octal 24
Decimal 21 = Octal 25
Decimal 22 = Octal 26
Decimal 23 = Octal 27
Decimal 24 = Octal 30
Decimal 25 = Octal 31
Decimal 26 = Octal 32
Decimal 27 = Octal 33
Decimal 28 = Octal 34
Decimal 29 = Octal 35
Decimal 30 = Octal 36
Decimal 31 = Octal 37
Decimal 32 = Octal 40
Decimal 33 = Octal 41
Decimal 34 = Octal 42
Decimal 35 = Octal 43
Decimal 36 = Octal 44
Decimal 37 = Octal 45
Decimal 38 = Octal 46
Decimal 39 = Octal 47
Decimal 40 = Octal 50
Decimal 41 = Octal 51
Decimal 42 = Octal 52
Decimal 43 = Octal 53
Decimal 44 = Octal 54
Decimal 45 = Octal 55
Decimal 46 = Octal 56
Decimal 47 = Octal 57
Decimal 48 = Octal 60
Decimal 49 = Octal 61
Decimal 50 = Octal 62``````

#### Raku solution

``````# Test: perl6 ch1.p6
use v6.d;

sub MAIN() {
for (1..50) -> \$i {
say 'Decimal '  ~ \$i ~
' = Octal ' ~ to-octal(\$i);
}
}

sub to-octal(Int \$i) {
return sprintf('%o', \$i);
}``````

Output

``````Decimal 1 = Octal 1
Decimal 2 = Octal 2
Decimal 3 = Octal 3
Decimal 4 = Octal 4
Decimal 5 = Octal 5
Decimal 6 = Octal 6
Decimal 7 = Octal 7
Decimal 8 = Octal 10
Decimal 9 = Octal 11
Decimal 10 = Octal 12
Decimal 11 = Octal 13
Decimal 12 = Octal 14
Decimal 13 = Octal 15
Decimal 14 = Octal 16
Decimal 15 = Octal 17
Decimal 16 = Octal 20
Decimal 17 = Octal 21
Decimal 18 = Octal 22
Decimal 19 = Octal 23
Decimal 20 = Octal 24
Decimal 21 = Octal 25
Decimal 22 = Octal 26
Decimal 23 = Octal 27
Decimal 24 = Octal 30
Decimal 25 = Octal 31
Decimal 26 = Octal 32
Decimal 27 = Octal 33
Decimal 28 = Octal 34
Decimal 29 = Octal 35
Decimal 30 = Octal 36
Decimal 31 = Octal 37
Decimal 32 = Octal 40
Decimal 33 = Octal 41
Decimal 34 = Octal 42
Decimal 35 = Octal 43
Decimal 36 = Octal 44
Decimal 37 = Octal 45
Decimal 38 = Octal 46
Decimal 39 = Octal 47
Decimal 40 = Octal 50
Decimal 41 = Octal 51
Decimal 42 = Octal 52
Decimal 43 = Octal 53
Decimal 44 = Octal 54
Decimal 45 = Octal 55
Decimal 46 = Octal 56
Decimal 47 = Octal 57
Decimal 48 = Octal 60
Decimal 49 = Octal 61
Decimal 50 = Octal 62``````

## Hard Challenge

Balanced Brackets

Write a script to generate a string with random number of ( and ) brackets. Then make the script validate the string if it has balanced brackets.

For example:

() – OK
(()) – OK
)( – NOT OK
())() – NOT OK

For this challenge I first decided to implement some recursive regex and event used https://metacpan.org/pod/Regexp::Common but it was failing to match correct on some edge cases where a parenthsis block was complete like ()((.

I didn’t want to spend too much time trying to figure the perfect regex so I validated using a cheap and efficient open parenthesis counter.

I did the same thing for Raku.

#### Perl 5 solution

``````#!/usr/bin/perl
# test: ./ch2.pl
use strict;
use warnings;
use feature qw /say/;
use constant {
MAX_STRING_LENGTH => 4
};

for my \$i ( 1 .. 20 ) {
my \$string = generate_random_string();
my \$ok = (validate_string(\$string)) ? 'OK ' : 'NOT OK';
say \$string . ' - ' . \$ok;
}

sub generate_random_string {
my \$length = int(rand(MAX_STRING_LENGTH - 1) + 2);
my \$string;

for my \$i (1 .. \$length ) {
\$string .= (int(rand(2))) ? '(' : ')';
}

return \$string;
}

sub validate_string {
my \$open_p;

for my \$char (split('', shift)) {
\$open_p++ if (\$char eq '(');
\$open_p-- if (\$char eq ')');

return 0 if (\$open_p < 0);
}

return (\$open_p == 0);
}
``````

Output

)(( – NOT OK
()() – OK
)(( – NOT OK
)) – NOT OK
()( – NOT OK
)( – NOT OK
(( – NOT OK
(() – NOT OK
()() – OK
)( – NOT OK
(() – NOT OK
)) – NOT OK
)( – NOT OK
)(() – NOT OK
(()) – OK
)))) – NOT OK
)) – NOT OK
() – OK
)() – NOT OK
)((( – NOT OK

#### Raku solution

``````# Test: perl6 ./ch2.p6
use v6.d;
constant \$MAX_STRING_LENGTH = 4;

sub MAIN () {
for ( 1 .. 20 ) {
my \$string = generate-random-string();
my \$ok = (validate-string(\$string)) ?? 'OK ' !! 'NOT OK';
say \$string ~ ' - ' ~ \$ok;
}
}

sub generate-random-string {
return <( )>.roll(
Int((2 .. \$MAX_STRING_LENGTH + 1).rand)
).join;
}

sub validate-string(Str \$word) {
my \$open_p;

for \$word.comb -> \$letter {
\$open_p++ if (\$letter eq '(');
\$open_p-- if (\$letter eq ')');
return 0 if (\$open_p < 0);
}

return (\$open_p == 0);
}
``````

Output

()( – NOT OK
)(( – NOT OK
()) – NOT OK
((( – NOT OK
)() – NOT OK
)()( – NOT OK
(() – NOT OK
() – OK
)))) – NOT OK
(() – NOT OK
(( – NOT OK
() – OK
(((( – NOT OK
(()) – OK
)))) – NOT OK
)()) – NOT OK
)( – NOT OK
() – OK
()() – OK
((( – NOT OK