diff options
| -rwxr-xr-x | challenge-042/ryan-thompson/extras/prob.pl | 37 | ||||
| -rwxr-xr-x | challenge-042/ryan-thompson/perl5/ch-2.pl | 34 | ||||
| -rw-r--r-- | challenge-042/ryan-thompson/perl6/ch-2.p6 | 22 |
3 files changed, 93 insertions, 0 deletions
diff --git a/challenge-042/ryan-thompson/extras/prob.pl b/challenge-042/ryan-thompson/extras/prob.pl new file mode 100755 index 0000000000..37455c51fe --- /dev/null +++ b/challenge-042/ryan-thompson/extras/prob.pl @@ -0,0 +1,37 @@ +#!/usr/bin/env perl +# +# ch-2.pl - Validate balanced brackets +# +# 2020 Ryan Thompson <rjt@cpan.org> + +use 5.010; +use warnings; +use strict; +no warnings 'uninitialized'; +use List::Util 'shuffle'; + +# To have any hope of being balanced, the string must be of even length, +# and must contain the same number of ( and ) brackets, so that's what we do. +sub gen_str { join '', shuffle map { ($_) x $_[0] } qw<( )> } + +# This type of balance checking is trivial with a regex +sub balanced(_) { $_[0] =~ /^(\((?1)*\))*$/ } + +use Algorithm::Combinatorics 'combinations'; +use Number::Fraction; + +# Check all strings of length 0..20 +for my $n (0..10) { + my $iter = combinations( [0 .. 2*$n-1], $n ); + + my ($bal, $tot); + while (my $i = $iter->next) { + my @a = ('(') x (2 * $n); + @a[@$i] = (')') x $n; + + $tot++; + $bal++ if balanced join '', @a; + } + printf "n = %2d: %5d / %-6d = %s\n", + $n, $bal, $tot, Number::Fraction->new($bal, $tot); +} diff --git a/challenge-042/ryan-thompson/perl5/ch-2.pl b/challenge-042/ryan-thompson/perl5/ch-2.pl new file mode 100755 index 0000000000..f569fd7b0d --- /dev/null +++ b/challenge-042/ryan-thompson/perl5/ch-2.pl @@ -0,0 +1,34 @@ +#!/usr/bin/env perl +# +# ch-2.pl - Validate balanced brackets +# +# Ryan Thompson <rjt@cpan.org> + +use 5.010; +use warnings; +use strict; +use List::Util 'shuffle'; + +# To have any hope of being balanced, the string must be of even length, +# and must contain the same number of ( and ) brackets, so that's what we do. +sub gen_str { join '', shuffle map { ($_) x $_[0] } qw<( )> } + +# This type of balance checking is trivial with a regex +sub balanced_tiny(_) { $_[0] =~ /^(\((?1)*\))*$/ } + +# Same sub, less line noise +sub balanced(_) { + $_[0] =~ /^ # Start of string + ( # Match group 1 + \( # Opening bracket + (?1)* # Recurse to start of group 1 + \) # Closing bracket + )* # Group 1, zero or more times + $/x # End of string +} + +# And now we'll check a few +for my $n (0..5) { + say "$_ - " . (balanced ? 'OK' : 'NOT OK') for map { gen_str($n) } 1..5; +} + diff --git a/challenge-042/ryan-thompson/perl6/ch-2.p6 b/challenge-042/ryan-thompson/perl6/ch-2.p6 new file mode 100644 index 0000000000..eda0b037ac --- /dev/null +++ b/challenge-042/ryan-thompson/perl6/ch-2.p6 @@ -0,0 +1,22 @@ +#!/usr/bin/env perl6 + +# ch-2.p6 - Balanced Braces +# +# Ryan Thompson <rjt@cpan.org> + +# First, the generator +sub gen-str( Int $half-len ) { ('()' x $half-len).comb.pick(*).join } + +# And now, the checker +sub balanced( Str $str is copy --> Bool ) { + Nil while $str ~~ s:g/'()'//; + $str.chars == 0 +} + +# Check a few +say "0 length - ", balanced('') ?? 'OK' !! 'NOT OK'; # No need to repeat this +for 1..5 -> $n { + for (^5).map({ gen-str($n) }) -> $str { + say "$str - ", balanced($str) ?? 'OK' !! 'NOT OK'; + } +} |
