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

"ch-1.pl" Defined by 1.

"ch-2.pl" Defined by 5.

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.

"ch-1.pl" 1


preamble 2
defang recursively 3
main 4

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.

preamble 2 ⟩≡


use v5.38;

Fragment referenced in 1, 5.

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!

defang recursively 3 ⟩≡


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 4 ⟩≡


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.

"ch-2.pl" 5


preamble 2
string score 6
main 7

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.

string score 6 ⟩≡


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 7 ⟩≡


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

The Weekly Challenge 272
Generated Code

posted at: 00:14 by: Adam Russell | path: /perl | permanent link to this entry