Perl Weekly Challenge 273: B After A

These are some answers to the Week 273, Task 2, of the Perl Weekly Challenge organized by Mohammad S. Anwar.

Spoiler Alert: This weekly challenge deadline is due in a few days from now (on June 16, 2024 at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.

Task 2: B After A

You are given a string, $str.

Write a script to return true if there is at least one b, and no a appears after the first b.

Example 1

Input: $str = "aabb"
Output: true

Example 2

Input: $str = "abab"
Output: false

Example 3

Input: $str = "aaa"
Output: false

Example 4

Input: $str = "bbb"
Output: true

This is a perfect job for regexes, both in Perl and Raku.

B After A in Raku

Our solution is essentially a one-liner with a regex. Since the Raku regex syntax is slightly different from the canonical Perl or Perl-compatible regex syntax, let me briefly explain the regex pattern used in the program below. First, spaces are not significant in Raku regexes (unless explicitly specified otherwise), so they can be used to separate or regroup pattern pieces and make them more readable and easier to understand. The regex below is made of 5 pieces:

^       beginning of string
<-[b]>* a character class meaning anything other than "b", repeated 0
        or more times
b       a literal "b"
<-[a]>* a character class meaning anything other than "a", repeated 0
        or more times
$       end of string

This is now the full program:

sub b-after-a ($str) {
    return $str ~~ /^ <-[b]>* b <-[a]>* $/ ?? True !! False;
}

for <aabb abab aaa bbb> ->  $test {
    printf "%-5s => ", $test;
    say b-after-a $test;
}

This program displays the following output.

$ raku ./b-after-a.raku
aabb  => True
abab  => False
aaa   => False
bbb   => True

B After A in Perl

This is a port to Perl of the above Raku program.

use strict;
use warnings;
use feature 'say';

sub b_after_a {
    return shift =~ /^[^b]*b[^a]*$/ ? "true" : "false";
}

for my $test (qw<aabb abab aaa bbb>) {
    printf "%-5s => ", $test;
    say b_after_a $test;
}

This program displays the following output.

$ perl ./b-after-a.pl
aabb  => true
abab  => false
aaa   => false
bbb   => true

Wrapping up

The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on June 23, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.

Leave a comment

About laurent_r

user-pic I am the author of the "Think Perl 6" book (O'Reilly, 2017) and I blog about the Perl 5 and Raku programming languages.