aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xchallenge-042/ryan-thompson/extras/prob.pl37
-rwxr-xr-xchallenge-042/ryan-thompson/perl5/ch-2.pl34
-rw-r--r--challenge-042/ryan-thompson/perl6/ch-2.p622
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';
+ }
+}