# RogerBW's Blog

Perl Weekly Challenge 61: maximum products and IPv4 20 May 2020

I’ve been doing the Perl Weekly Challenges. The latest involved searching for the maximum product in a sequence, and un-munging IPv4 addresses.

Given a list of 4 or more numbers, write a script to find the contiguous sublist that has the maximum product. The length of the sublist is irrelevant; your job is to maximize the product.

Example

Input: [ 2, 5, -1, 3 ]

Output: [ 2, 5 ] which gives maximum product 10.

Why?

This combines two things for which I already have standard patterns: "doubly iterate over a list" and "keep the maximum value and the parameters used to generate it". All quite straightforward.

``````my (\$mxp,\$a,\$b);

foreach my \$ai (0..\$#list) {
foreach my \$bi (\$ai..\$#list) {
my \$p=1;
map {\$p*=\$_} @list[\$ai..\$bi];
if (!defined \$mxp || \$p > \$mxp) {
(\$mxp,\$a,\$b)=(\$p,\$ai,\$bi);
}
}
}

print join(' * ',@list[\$a..\$b]),' = ',\$mxp,"\n";
``````

Raku differs only in details of syntax.

You are given a string containing only digits (0..9). The string should have between 4 and 12 digits.

Write a script to print every possible valid IPv4 address that can be made by partitioning the input string.

For the purpose of this challenge, a valid IPv4 address consists of four “octets” i.e. A, B, C and D, separated by dots (.).

Each octet must be between 0 and 255, and must not have any leading zeroes. (e.g., 0 is OK, but 01 is not.)

Example

Input: 25525511135,

Output:

255.255.11.135

255.255.111.35

And this ends up being a standard search with ring buffer. Each entry consists of the octets approved so far, and any remaining matter at the end. The remaining matter is parsed to see if a new octet can be extract from it.

``````my @buf=([\$in]);
while (my \$t=shift @buf) {
my @l=@{\$t};
my \$r=pop @l;
if (\$r eq '' && scalar @l == 4) {
print join('.',@l),"\n";
}
if (scalar @l >= 4) {
next;
}
foreach my \$fl (1..min(3,length(\$r))) {
my \$a=substr(\$r,0,\$fl);
``````

One could do this bit with regular expressions, but this seemed cleaner: the number is not greater than 255, and either it's zero or it doesn't start with a zero.

``````    if (\$a <= 255 && (\$a==0 || \$a =~ /^[1-9]/)) {
my \$b=substr(\$r,\$fl);
push @buf,[@l,substr(\$r,0,\$fl),\$b];
}
}
}
``````

I didn't do this one in Raku - that whole list-of-lists thing is a pain, because the language keeps trying to be clever and infer what I want. If I used Raku for anything other than these challenges, I'd settle down and work out just how to get a plain old mutable list of mutable lists with no sugar involved… but I don't, because while parts of the language are great fun to use it's so curst slow as soon as it gets down to anything useful.