Advent Calendar 2020
| Day 6 | Day 7 | Day 8 |
The gift is presented by Javier Luque. Today he is talking about his solution to the task IPv4 Partition
of “The Weekly Challenge - 061”. This is re-produced for Advent Calendar 2020 from the original post by Javier Luque.
IPv4 Partition
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
For this challenge I brute forced the solution my finding all the possible locations of the . then checking the string if its a valid IP address.
so a string like: 12345
Will produce these combinations
1.2.3.45
1.2.34.5
1.23.4.5
12.3.4.5
Perl
#!/usr/bin/perl
# Test: ./ch-2.pl
use strict;
use warnings;
use feature qw /say/;
use Algorithm::Combinatorics qw(combinations);
my $ip_address = $ARGV[0] || '25525511135';
partition_ip_string($ip_address);
# Partition the ip string
sub partition_ip_string {
my $string = shift;
my $length = length($string) - 2;
# Validate string
return undef if
( length($string) < 4 ||
length($string) > 12 ||
!($string =~ /^\d+$/)
);
# Find all the combinations for the possible ips
my @dot_positions = (0 .. $length);
my $iter = combinations(\@dot_positions, 3);
# Process the combinations
while (my $combos = $iter->next) {
my $to_test = $string;
my $offset = 0;
for my $dot_position (@$combos) {
my $position =
($dot_position + $offset) + 1;
# Append to the test string;
$to_test =
(substr $to_test, 0, $position)
. '.' .
(substr $to_test, $position);
# Offset the string
$offset++;
}
say $to_test
if (validate_ip_string($to_test));
}
}
# Validate the IP String
sub validate_ip_string {
for my $digit (split('\.', shift)) {
return 0 if ($digit > 255);
return 0 if ($digit =~ /^0\d+$/);
}
return 1;
}
Output perl ch-2.pl
255.255.11.135
255.255.111.35
Raku
# Test: perl6 ch-2.p6
multi MAIN() {
MAIN('25525511135');
}
multi MAIN(Str $str) {
partition-ip-string($str);
}
# Partition the ip string
sub partition-ip-string (Str $str) {
my $length = $str.chars - 2;
# Find all the combinations for the possible ips
my @dot_positions = (0 .. $length);
my @combos = @dot_positions.combinations: 3;
# Process the combinations
for @combos -> @combo {
my $to_test = $str;
my $offset = 0;
for (@combo) -> $dot_position {
my $position =
($dot_position + $offset) + 1;
# Append to the test string;
$to_test =
$to_test.substr(0, $position)
~ '.' ~
$to_test.substr($position);
# Offset the string
$offset++;
}
say $to_test
if (validate-ip-string($to_test));
}
}
# Validate the IP String
sub validate-ip-string(Str $str) {
for $str.split('.') -> $digit {
return False if ($digit > 255);
return False if ($digit ~~ /^0\d+$/);
}
return True;
}
Output perl6 ch-2.p6
255.255.11.135
255.255.111.35
If you have any suggestion then please do share with us perlweeklychallenge@yahoo.com.