from typing import List
def ipToCIDR(ip: str, n: int) -> List[str]:
def ip2int(ip):
parts = list(map(int, ip.split('.')))
res = 0
for part in parts:
res = res * 256 + part
return res
def int2ip(x):
return '.'.join(str((x >> (8 * i)) & 255) for i in reversed(range(4)))
res = []
start = ip2int(ip)
while n > 0:
max_size = start & -start
max_block = 1
while max_block & start == 0:
max_block <<= 1
while max_block > n:
max_block >>= 1
size = max(max_size, max_block)
while size > n:
size >>= 1
mask = 32 - size.bit_length() + 1
res.append(f"{int2ip(start)}/{mask}")
start += size
n -= size
return res
#include <vector>
#include <string>
using namespace std;
class Solution {
public:
vector<string> ipToCIDR(string ip, int n) {
vector<string> res;
long start = ip2long(ip);
while (n > 0) {
long max_size = start & -start;
long size = 1;
while (size & start == 0) size <<= 1;
while (size > n) size >>= 1;
size = max(max_size, size);
while (size > n) size >>= 1;
int mask = 32 - bit_length(size) + 1;
res.push_back(long2ip(start) + "/" + to_string(mask));
start += size;
n -= size;
}
return res;
}
private:
long ip2long(string ip) {
long res = 0;
int val = 0;
for (char c : ip) {
if (c == '.') {
res = res * 256 + val;
val = 0;
} else {
val = val * 10 + (c - '0');
}
}
res = res * 256 + val;
return res;
}
string long2ip(long x) {
return to_string((x >> 24) & 255) + "." + to_string((x >> 16) & 255) + "." +
to_string((x >> 8) & 255) + "." + to_string(x & 255);
}
int bit_length(long x) {
int len = 0;
while (x) {
++len;
x >>= 1;
}
return len;
}
};
import java.util.*;
class Solution {
public List<String> ipToCIDR(String ip, int n) {
List<String> res = new ArrayList<>();
long start = ip2long(ip);
while (n > 0) {
long max_size = start & -start;
long size = 1;
while ((size & start) == 0) size <<= 1;
while (size > n) size >>= 1;
size = Math.max(max_size, size);
while (size > n) size >>= 1;
int mask = 32 - Long.toBinaryString(size).length() + 1;
res.add(long2ip(start) + "/" + mask);
start += size;
n -= size;
}
return res;
}
private long ip2long(String ip) {
String[] parts = ip.split("\\.");
long res = 0;
for (String part : parts) {
res = res * 256 + Integer.parseInt(part);
}
return res;
}
private String long2ip(long x) {
return String.format("%d.%d.%d.%d", (x >> 24) & 255, (x >> 16) & 255, (x >> 8) & 255, x & 255);
}
}
function ipToCIDR(ip, n) {
function ip2int(ip) {
return ip.split('.').reduce((acc, x) => acc * 256 + Number(x), 0);
}
function int2ip(x) {
return [(x >>> 24) & 255, (x >>> 16) & 255, (x >>> 8) & 255, x & 255].join('.');
}
let res = [];
let start = ip2int(ip);
while (n > 0) {
let max_size = start & -start;
let size = 1;
while ((size & start) === 0) size <<= 1;
while (size > n) size >>= 1;
size = Math.max(max_size, size);
while (size > n) size >>= 1;
let mask = 32 - Math.floor(Math.log2(size)) + 1;
res.push(int2ip(start) + "/" + mask);
start += size;
n -= size;
}
return res;
}
ip
and an integer n
representing the number of IP addresses to cover, your task is to return the smallest list of CIDR (Classless Inter-Domain Routing) blocks that exactly cover the range of n
IP addresses starting from ip
. Each CIDR block should be in the format a.b.c.d/x
, where x
is the prefix length. You must not reuse or overlap IPs, and your output must cover all the IPs in the range exactly once. There is at least one valid solution.
n
, reduce the block size to fit.n
accordingly.n
addresses have been covered.ip = "255.0.0.7"
and n = 10
.
n
.