B of A
with Raku

by Arne Sommer

B of A with Raku

[293] Published 15. June 2024.

This is my response to The Weekly Challenge #273.

Challenge #273.1: Percentage of Character

You are given a string, $str and a character $char.

Write a script to return the percentage, nearest whole, of given character in the given string.

Example 1:
Input: $str = "perl", $char = "e"
Output: 25
Example 2:
Input: $str = "java", $char = "a"
Output: 50
Example 3:
Input: $str = "python", $char = "m"
Output: 0
Example 4:
Input: $str = "ada", $char = "a"
Output: 67
Example 5:
Input: $str = "ballerina", $char = "l"
Output: 22
Example 6:
Input: $str = "analitik", $char = "k"
Output: 13
File: percentage-of-character
#! /usr/bin/env raku

unit sub MAIN ($str where $str.chars > 0, $char where $char.chars == 1); # [1]

say ( (100 * $str.comb.Bag{$char} / $str.chars) + 0.5).int;              # [2]

[1] The string must have at least one character, and the character must be one character only.

[2] Start with the string, apply comb to turn it into an array of individual characters, then Bag to turn it into a - suprise - Bag which is a hash like structure where the keys are the characters in the array, and the values are the frequency. Then we look up the character in that Bag to get the frequency. Then we apply some math to get the percentage of the whole.

See docs.raku.org/routine/Bag for more information about Bag.

Running it:

$ ./percentage-of-character perl e
25

$ ./percentage-of-character java a
50

$ ./percentage-of-character python m
0

$ ./percentage-of-character ada a
67

$ ./percentage-of-character ballerina l
22

$ ./percentage-of-character analitik k
13

Looking good.

Verbose mode did make much sense for what is basically a one liner.

Challenge #273.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

File: b-after-a
#! /usr/bin/env raku

unit sub MAIN ($str where $str.chars > 0);  # [1]

if $str ~~ /b/                              # [2]
{
  my $after = $str.split(/b/, 2)[1];        # [3]

  if $after !~~ /a/                         # [4]
  {
    say 'true';                             # [4a]
    exit;                                   # [4b]
  }
}

say 'false';                                # [5]

[1] Ensure a string with at least one character, because - why not?

[2] Does the string contain at least one «b»?

[3] If so, split the string where it contains one «b». The ,2 part tells split to only give us two strings (i.e. split on the first «b» only). Then we apply [1] to get the second element in the resulting array, the part after the first «b».

See docs.raku.org/routine/split for more information about split.

[4] If we do not find an «a» in this string, report success [4a] and exit [4b].

[5] In all other cases, we have failed. Say so.

Running it:

$ ./b-after-a aabb
true

$ ./b-after-a abab
false

$ ./b-after-a aaa
false

$ ./b-after-a bbb
true

Looking good.

No verbose mode for this one either.

And that's it.