Perl Weekly Challenge 272: String Score
These are some answers to the Week 272, 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 9, 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: String Score
You are given a string, $str
.
Write a script to return the score of the given string.
The score of a string is defined as the sum of the absolute difference between the ASCII values of adjacent characters.
Example 1
Input: $str = "hello"
Output: 13
ASCII values of characters:
h = 104
e = 101
l = 108
l = 108
o = 111
Score => |104 - 101| + |101 - 108| + |108 - 108| + |108 - 111|
=> 3 + 7 + 0 + 3
=> 13
Example 2
Input: "perl"
Output: 30
ASCII values of characters:
p = 112
e = 101
r = 114
l = 108
Score => |112 - 101| + |101 - 114| + |114 - 108|
=> 11 + 13 + 6
=> 30
Example 3
Input: "raku"
Output: 37
ASCII values of characters:
r = 114
a = 97
k = 107
u = 117
Score => |114 - 97| + |97 - 107| + |107 - 117|
=> 17 + 10 + 10
=> 37
In some programming languages, you can subtract characters directly. For example, 'c' - 'a'
would yield 2. In Perl and in Raku, you need to use the ord
method or function to explicitly convert characters to their ASCII values before you can perform the subtraction..
String Score in Raku
Not much to say. We loop through the letters of the input string, convert them to ASCII values, perform the subtraction and add the absolute value of the difference to the result.
sub string-score ($in) {
my $result = 0;
my @let = $in.comb;
for 1 .. @let.end -> $i {
$result += (@let[$i].ord - @let[$i - 1].ord).abs;
}
return $result;
}
for <hello perl raku> -> $test {
printf "%-8s => ", $test;
say string-score $test;
}
This program displays the following output:
$ raku ./string-score.raku
hello => 13
perl => 30
raku => 37
String Score in Perl
This is a port to Perl of the above Raku program.
use strict;
use warnings;
use feature 'say';
sub string_score {
my $result = 0;
my @let = split //, shift;
for my $i (1 .. $#let) {
$result += abs (ord($let[$i]) - ord($let[$i - 1]));
}
return $result;
}
for my $test (qw<hello perl raku>) {
printf "%-8s => ", $test;
say string_score $test;
}
This program displays the following output:
$ perl string-score.pl
hello => 13
perl => 30
raku => 37
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 16, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.
Leave a comment