codility/lib/BinaryGap.pm
2023-09-20 21:50:08 -05:00

64 lines
No EOL
1.5 KiB
Perl

package BinaryGap;
use Modern::Perl;
# use List::MoreUtils qw(first_index); # codility does not have
use List::Util qw(max first);
use Data::Dumper;
sub solution {
# N is an integer within the range [1..2,147,483,647]
my ($N) = @_;
my $max_gap = 0;
# Make sure number is in acceptable range, if not return 0
if (($N < 1) || ($N > '2147483647')) {
return $max_gap;
}
# convert integer to binary
my $bin_num = unpack("B*", pack("N", $N));
# convert to array
my @bin_array = split('',$bin_num);
# find first 1. If there is not one, return for performance
my $first_index;
for (0 .. $#bin_array) {
if ($bin_array[$_] == 1) {
$first_index = $_;
last;
}
}
return $max_gap unless $first_index;
# If there are less than two 1s in the array, return 0
my $ones_total_count = grep { $_ == 1 } @bin_array;
if ($ones_total_count < 2) {
return $max_gap;
}
# If there is just one 0 in the array, return 0
my $zeros_total_count = grep { $_ == 0 } @bin_array;
if ($zeros_total_count < 2) {
return $max_gap;
}
# Get all 1 indexes
my @i = grep { $bin_array[$_] == 1 } 0 .. $#bin_array;
my $last_index = $i[$#i];
my $zero_count = 0;
for my $index ($first_index .. $last_index) {
my $num = $bin_array[$index];
if ($num == 1) {
$zero_count = 0;
}
else {
$zero_count++;
$max_gap = max($zero_count, $max_gap);
}
}
return $max_gap;
}
1;