Implement an IPv4 Range Iterator
Company: OpenAI
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates implementing iterative data structures and range-handling algorithms alongside numeric representation of IPv4 addresses and bit-level conversions between dotted-decimal strings and 32-bit integers.
Constraints
- 1 <= len(operations) <= 200000
- 0 <= len(ranges) <= 200000
- Each IPv4 address is valid and in the range 0.0.0.0 to 255.255.255.255
- Each range is inclusive and satisfies start_ip <= end_ip numerically
- The total number of IPs represented by the ranges may be much larger than len(operations), so do not expand all addresses eagerly
Examples
Input: ([('10.0.0.3', '10.0.0.5'), ('10.0.0.1', '10.0.0.2')], ['has_next', 'next', 'next', 'next', 'next', 'next', 'has_next'])
Expected Output: [True, '10.0.0.1', '10.0.0.2', '10.0.0.3', '10.0.0.4', '10.0.0.5', False]
Explanation: The two ranges are adjacent after sorting, so they merge into one continuous range from 10.0.0.1 to 10.0.0.5.
Input: ([('192.168.1.12', '192.168.1.13'), ('192.168.1.10', '192.168.1.11')], ['next', 'next', 'has_next', 'next', 'next'])
Expected Output: ['192.168.1.10', '192.168.1.11', True, '192.168.1.12', '192.168.1.13']
Explanation: The ranges are adjacent and normalize into 192.168.1.10 through 192.168.1.13.
Input: ([], ['has_next', 'has_next'])
Expected Output: [False, False]
Explanation: With no ranges, the iterator is empty from the beginning.
Input: ([('0.0.0.0', '0.0.0.0'), ('0.0.0.0', '0.0.0.1')], ['has_next', 'next', 'next', 'has_next'])
Expected Output: [True, '0.0.0.0', '0.0.0.1', False]
Explanation: The ranges overlap and merge into 0.0.0.0 through 0.0.0.1.
Input: ([('255.255.255.254', '255.255.255.255'), ('255.255.255.255', '255.255.255.255')], ['next', 'has_next', 'next', 'has_next'])
Expected Output: ['255.255.255.254', True, '255.255.255.255', False]
Explanation: This checks correct handling of the highest IPv4 values and overlapping ranges.
Input: ([('1.1.1.1', '1.1.1.2'), ('1.1.1.4', '1.1.1.4')], ['next', 'next', 'has_next', 'next', 'has_next'])
Expected Output: ['1.1.1.1', '1.1.1.2', True, '1.1.1.4', False]
Explanation: The ranges are separate, so the iterator must skip the gap and continue with the next merged interval.
Hints
- Comparing IPv4 strings lexicographically is not enough. Convert each address to a 32-bit integer first.
- Sort the intervals, merge overlaps or adjacent ranges, then keep a pointer to the current interval and current IP so each operation is O(1) after preprocessing.