RabbitFarm
2024-06-08
Defanged and Scored
The examples used here are from the weekly challenge problem statement and demonstrate the working solution.
File Index
Part 1: Defang IP Address
You are given a valid IPv4 address. Write a script to return the defanged version of the given IP address. A defanged IP address replaces every period “.” with “[.]".
The complete solution is contained in one file that has a simple structure.
For this problem we do not need to include very much. We’re just specifying to use the current version of Perl, for all the latest features in the language. This fragment is also used in Part 2.
First, let’s consider how we know to make string substitutions. Regular Expressions are an obvious choice. Maybe a little too obvious to be fun. We could also convert the string to a list of characters and then loop over the list making adjustments as necessary. That sounds nicer. Instead of some ordinary loop though let’s add a little recursive spice!
-
sub defang{
my($c, $defanged) =
@_;
$defanged = [] if !$defanged;
return $defanged if
@{$c} == 0;
my $x = shift
@{$c};
if($x eq q/./){
push
@{$defanged}, q/[.]/;
}
else{
push
@{$defanged}, $x;
}
defang($c, $defanged);
}
◇
-
Fragment referenced in 1.
-
Defines:
$defanged
Never used.
Now all we need are a few lines of code for running some tests.
-
MAIN:{
say join(q//,
@{defang([split //, q/1.1.1.1/])});
say join(q//,
@{defang([split //, q/255.101.1.0/])});
}
◇
-
Fragment referenced in 1.
Sample Run
$ perl perl/ch-1.pl 1[.]1[.]1[.]1 255[.]101[.]1[.]0
Part 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.
We’ll contain the solution in a single function. The completed solution will just have that function plus a few tests. Instead of recursion this time we’ll use a redo block.
This is our principal function. As can be seen, it’s very short! The logic here is simple: peel off characters until there’s just one left. Calculate the string score each time through. Well, to simplify things we’ll first actually convert the characters to their ascii values. That’s what the map at the start of the function does.
-
sub string_score{
my($s) = shift;
my $score = 0;
my
@s = map {ord $_} split //, $s;
{
my $x = shift
@s;
my $y = shift
@s;
$score += abs($x - $y) if $x && $y;
unshift
@s, $y;
redo if
@s > 1;
}
return $score;
}
◇
-
Fragment referenced in 5.
Finally, here’s a few tests to confirm everything is working right.
-
MAIN:{
say string_score q/hello/;
say string_score q/perl/;
say string_score q/raku/;
}
◇
-
Fragment referenced in 5.
Sample Run
$ perl ch-2.pl 13 30 37
References
posted at: 00:14 by: Adam Russell | path: /perl | permanent link to this entry