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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s