Perl Weekly Challenge 272.

My solutions (task 1 and task 2 ) to the The Weekly Challenge - 272.

Task 1: Defang IP Address

Submitted by: Mohammad Sajid Anwar
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 “[.]".

Example 1
Input: $ip = "1.1.1.1"
Output: "1[.]1[.]1[.]1"
Example 2
Input: $ip = "255.101.1.0"
Output: "255[.]101[.]1[.]0"

Am I missing something? Seems a very trivial global replacement which may be performed by a half-liner.

Examples:

perl -E 'for(@ARGV){$o=$_; s/\./[.]/g; say "$o -> $_"}' "1.1.1.1" "255.101.1.0"

Results:

1.1.1.1 -> 1[.]1[.]1[.]1
255.101.1.0 -> 255[.]101[.]1[.]0

The full code adds some checks

 1  # Perl weekly challenge 272
 2  # Task 1:  Defang IP Address
 3  #
 4  # See https://wlmb.github.io/2024/06/03/PWC272/#task-1-defang-ip-address
 5  use v5.36;
 6  die <<~"FIN" unless @ARGV;
 7      Usage: $0 A1 A2...
 8      to defang the IP addresses A1 A2...
 9      FIN
10  my $ip=join '\.', ('\d{1,3}') x 4;
11  for(@ARGV){
12      my $original=$_;
13      warn "Not a valid IP: $_", next unless /^$ip$/;
14      s/\./[.]/g;
15      say "$original -> $_";
16  }

Example:

./ch-1.pl "1.1.1.1" "255.101.1.0"

Results:

1.1.1.1 -> 1[.]1[.]1[.]1
255.101.1.0 -> 255[.]101[.]1[.]0

Task 2: String Score

Submitted by: Mohammad Sajid Anwar
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

The ord function returns the ascii value of the ascii characters in a string, which I can reduce by subtracting, taking the absolute value and adding. I can use PDL for this.

Examples:

perl -MPDL -MPDL::NiceSlice -E '
for(@ARGV){$a=pdl map {ord} split ""; say "$_ -> ",($a(1:-1)-$a(0:-2))->abs->sumover;}
' hello perl raku

Results:

hello -> 13
perl -> 30
raku -> 37

Full code:

 1  # Perl weekly challenge 272
 2  # Task 2:  String Score
 3  #
 4  # See https://wlmb.github.io/2024/06/03/PWC272/#task-2-string-score
 5  use v5.36;
 6  use PDL;
 7  use PDL::NiceSlice;
 8  die <<~"FIN" unless @ARGV;
 9      Usage: $0 S1 S2...
10      to find the score of the strings S1 S2...
11      i.e., the sum of the absolute value of
12      the difference of consecutive ascii values.
13      FIN
14  for(@ARGV){
15      my $ords=pdl map {ord} split "";
16      warn "Need at least two characters: $_", next unless $ords->nelem > 1;
17      say "$_ -> ",($ords(1:-1)-$ords(0:-2))->abs->sumover;
18  }

Example:

./ch-2.pl hello perl raku

Results:

hello -> 13
perl -> 30
raku -> 37
Written on June 3, 2024