Binary Gap
Find longest sequence of zeros in binary representation of an integer.
Problem
A binary gap within a positive integer N is any maximal sequence of consecutive zeros that is surrounded by ones at both ends in the binary representation of N.
For example, number 9 has binary representation 1001 and contains a binary gap of length 2. The number 529 has binary representation 1000010001 and contains two binary gaps: one of length 4 and one of length 3. The number 20 has binary representation 10100 and contains one binary gap of length 1. The number 15 has binary representation 1111 and has no binary gaps. The number 32 has binary representation 100000 and has no binary gaps.
Write a function:
def solution(N)
that, given a positive integer N, returns the length of its longest binary gap. The function should return 0 if N doesn't contain a binary gap.
Write an efficient algorithm for the following assumptions:
N is an integer within the range [1..2,147,483,647].
Example
For example, given N = 1041
The function should return 5, because N has binary representation 10000010001 and so its longest binary gap is of length 5.
Given N = 32
The function should return 0, because N has binary representation '100000' and thus no binary gaps.
Ideas For Code
Step 1: A binary gap can be represented using the RegEx:
1(0+)1
But this pattern would not be suffice because it would not work for a binary like: 10001001
As here the second one is part of two Binary Gaps (First ‘10001’ and second ‘1001’).
So we reduce the pattern to: 10+
This is to prevent overlap between binary gaps we want to capture.
Step 2: Find all such patterns in the binary of the integer
Step 3: Check if there is a closing one at the end
Step 4: Store the lengths of all such binary gaps
Step 5: Return the maximum length
Python Code (Version 1)
import re pattern = re.compile("10+") def solution(N): n = str(bin(N))[2:] matches = re.finditer(pattern, n) matches_ = [] lengths = [] for i in matches: if(len(n) > i.span()[1]): if(n[i.span()[1]] == '1'): matches_.append(i.group()) lengths.append(i.group().count('0')) if len(lengths) > 0: rtn = max(lengths) else: rtn = 0 return rtn
Can we do better?
Here in the Step 5 and 6: Where we want to print the maximum length
Here the Space Complexity is of the order of n, O(n) (number of binary gaps in input)
Step 5: Instead of storing all the lengths, we can simply store the maximum length across all the binary gaps.
Step 6: Return the maximum length obtained in Step 5
Also, there is added Time Complexity of finding the maximum length from all the accumulated lengths.
Python Code (Version 2)
import re pattern = re.compile("10+") def solution(N): n = str(bin(N))[2:] matches = re.finditer(pattern, n) matches_ = [] max_length = 0 for i in matches: if(len(n) > i.span()[1]): if(n[i.span()[1]] == '1'): matches_.append(i.group()) if i.group().count('0') > max_length: max_length = i.group().count('0') return max_length
Test Cases
- extremes
n=1, n=5=101_2 and n=2147483647=2**31-1
- trailing_zeroes
n=6=110_2 and n=328=101001000_2
- power_of_2
n=5=101_2, n=16=2**4 and n=1024=2**10
- simple1
n=9=1001_2 and n=11=1011_2
- medium1
n=51712=110010100000000_2 and n=20=10100_2
- large1
n=6291457=11000000000000000000001_2
Test Results
print("Testing...")
print(solution(1041))
print(solution(15))
print(solution(32))
print(solution(1))
print(solution(2147483647))
print(solution(6291457))
print(solution(74901729))
print(solution(805306373))
print(solution(1376796946))
print(solution(1073741825))
print(solution(1610612737))
Testing...
5
0
0
0
0
20
4
25
5
29
28
Future Scope
- How can we implement the same thing in JavaScript?
- How can we implement the same thing in Java?
Homework
Generate 10 random natural numbers and return the maximum number generated.
No comments:
Post a Comment