aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xchallenge-273/bruce-gray/perl/ch-1.pl33
-rwxr-xr-xchallenge-273/bruce-gray/perl/ch-2.pl18
-rwxr-xr-xchallenge-273/bruce-gray/python/ch-1.py22
-rwxr-xr-xchallenge-273/bruce-gray/python/ch-2.py19
-rw-r--r--challenge-273/bruce-gray/raku/ch-1.raku21
-rw-r--r--challenge-273/bruce-gray/raku/ch-2.raku43
6 files changed, 156 insertions, 0 deletions
diff --git a/challenge-273/bruce-gray/perl/ch-1.pl b/challenge-273/bruce-gray/perl/ch-1.pl
new file mode 100755
index 0000000000..6bea8e6242
--- /dev/null
+++ b/challenge-273/bruce-gray/perl/ch-1.pl
@@ -0,0 +1,33 @@
+#!perl
+use v5.36;
+use POSIX qw<lround>;
+
+# XXX challenge-273/e-choroba/perl/ch-1.pl shows \Q !!!
+
+sub task1 ($str, $char) {
+
+ my $count =()= $str =~ m{$char}g; # Google perlsecret.pod
+
+ return lround( 100 * $count / length($str) );
+}
+# As mentioned in PerlFAQ4, rounding via `sprintf '%.0f' would get the rounding wrong on `analitik`, since it uses "statistician's rounding", making `12.5` into `12` where `lround` give us the `13` that the task's example #6 lists as output. See:
+# https://perldoc.perl.org/perlfaq4#Does-Perl-have-a-round()-function?-What-about-ceil()-and-floor()?-Trig-functions?
+# https://en.wikipedia.org/wiki/Rounding#Rounding_half_to_even
+# https://pubs.opengroup.org/onlinepubs/9699919799/functions/round.html
+# https://pubs.opengroup.org/onlinepubs/9699919799/functions/lround.html
+
+# XXX credit lround and \Q!
+
+
+my @tests = qw<
+ perl e 25
+ java a 50
+ python m 0
+ ada a 67
+ ballerina l 22
+ analitik k 13
+>;
+use Test2::V0 -no_srand => 1; plan @tests/3;
+for my ( $str, $char, $expected ) (@tests) {
+ is task1( $str, $char ), $expected;
+}
diff --git a/challenge-273/bruce-gray/perl/ch-2.pl b/challenge-273/bruce-gray/perl/ch-2.pl
new file mode 100755
index 0000000000..a4f905bd3f
--- /dev/null
+++ b/challenge-273/bruce-gray/perl/ch-2.pl
@@ -0,0 +1,18 @@
+#!perl
+use v5.40;
+
+sub task2 ($str) {
+ return $str =~ / ^ [^b]* b [^a]* $ /msx;
+}
+
+
+my @tests = (
+ 'aabb' , true ,
+ 'abab' , false ,
+ 'aaa' , false ,
+ 'bbb' , true ,
+);
+use Test2::V0 -no_srand => 1; plan @tests/2;
+for my ( $str, $expected ) (@tests) {
+ is task2($str), $expected;
+}
diff --git a/challenge-273/bruce-gray/python/ch-1.py b/challenge-273/bruce-gray/python/ch-1.py
new file mode 100755
index 0000000000..804a3359a6
--- /dev/null
+++ b/challenge-273/bruce-gray/python/ch-1.py
@@ -0,0 +1,22 @@
+#!python
+import math
+def lround(n):
+ return math.floor(n + 0.5)
+
+def task1(str, char):
+ return lround(100 * str.count(char) / len(str))
+
+
+import unittest
+class TestTask1(unittest.TestCase):
+ def t(self, str, char, expected):
+ self.assertEqual(task1(str, char), expected, f"task1('{str}', '{char}')")
+
+ def test_1(self): self.t('perl' , 'e', 25)
+ def test_2(self): self.t('java' , 'a', 50)
+ def test_3(self): self.t('python' , 'm', 0)
+ def test_4(self): self.t('ada' , 'a', 67)
+ def test_5(self): self.t('ballerina' , 'l', 22)
+ def test_6(self): self.t('analitik' , 'k', 13)
+
+unittest.main()
diff --git a/challenge-273/bruce-gray/python/ch-2.py b/challenge-273/bruce-gray/python/ch-2.py
new file mode 100755
index 0000000000..d1ce92088f
--- /dev/null
+++ b/challenge-273/bruce-gray/python/ch-2.py
@@ -0,0 +1,19 @@
+#!python
+import re
+
+def task2(str):
+ p = re.compile('^[^b]*b[^a]*$')
+ return bool(p.match(str))
+
+
+import unittest
+class TestTask1(unittest.TestCase):
+ def t(self, str, expected):
+ self.assertEqual(task2(str), expected, f"task2('{str}')")
+
+ def test_1(self): self.t('aabb' , True )
+ def test_2(self): self.t('abab' , False)
+ def test_3(self): self.t('aaa' , False)
+ def test_4(self): self.t('bbb' , True )
+
+unittest.main()
diff --git a/challenge-273/bruce-gray/raku/ch-1.raku b/challenge-273/bruce-gray/raku/ch-1.raku
new file mode 100644
index 0000000000..4bb9143933
--- /dev/null
+++ b/challenge-273/bruce-gray/raku/ch-1.raku
@@ -0,0 +1,21 @@
+sub task1 ( $str, $char --> UInt ) {
+ my UInt $count = +$str.comb($char);
+ # Alternatives:
+ # $str.comb.Bag{$char} // 0;
+ # +$str.indices($char);
+
+ return round( 100 * $count / $str.chars );
+}
+
+
+use Test; plan +constant @tests =
+ <perl e 25>,
+ <java a 50>,
+ <python m 0>,
+ <ada a 67>,
+ <ballerina l 22>,
+ <analitik k 13>,
+;
+for @tests -> ( $str, $char, $expected ) {
+ is task1( $str, $char ), $expected;
+}
diff --git a/challenge-273/bruce-gray/raku/ch-2.raku b/challenge-273/bruce-gray/raku/ch-2.raku
new file mode 100644
index 0000000000..2690b8779d
--- /dev/null
+++ b/challenge-273/bruce-gray/raku/ch-2.raku
@@ -0,0 +1,43 @@
+# At least one b, and no a appears after the first b.
+sub task2_cont_regex_ladder ( $str --> Bool ) {
+ return False unless $str.contains('b');
+ return False if $str ~~ / b .* a /;
+ return True;
+}
+sub task2_cont_regex ( $str --> Bool ) {
+ return $str.contains('b')
+ && $str !~~ / b .* a /;
+}
+sub task2_index_substr_cont ( $str --> Bool ) {
+ my $pos_of_first_b = $str.index('b')
+ orelse return False;
+
+ return ! $str.substr($pos_of_first_b).contains('a');
+}
+# XXX credit jo-37 via ~/T/d20240614/n15.pl
+sub task2_single_regex ( $str --> Bool ) {
+ # return so $str ~~ / ^ <-[b]>* b <-[a]>* $ /;
+ # return so $str ~~ / ^ <-[b]>*: b <-[a]>*: $ /;
+ return so $str ~~ /:r ^ <-[b]>* b <-[a]>* $ /;
+ # https://docs.raku.org/language/regexes#Backtracking_control
+}
+
+
+my @tests =
+ ( 'aabb' , True ),
+ ( 'abab' , False ),
+ ( 'aaa' , False ),
+ ( 'bbb' , True ),
+;
+my @subs =
+ :&task2_cont_regex_ladder,
+ :&task2_cont_regex,
+ :&task2_index_substr_cont,
+ :&task2_single_regex,
+;
+use Test; plan +@tests * +@subs;
+for @subs -> ( :key($sub_name), :value(&task2) ) {
+ for @tests -> ( $str, $expected ) {
+ is task2($str), $expected, "$sub_name : $str";
+ }
+}