# 30. 根据IP查找城市

30 30-1

const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

const lines = [];
rl.on('line', (line) => {
    lines.push(line);
});
rl.on('close', () => {
    console.log(matchCities(lines[0], lines[1]));
})

function ipToLong(ip) {
    return ip.split('.').reduce((acc, octet) => (acc << 8) + parseInt(octet, 10))
}

function parseIpPool(ipPool) {
    const cityIpRanges = {};
    ipPool.split(';').forEach(cityRange => {
        const [city, range] = cityRange.split('=');
        const [startIp, endIp] = range.split(',');
        const start = ipToLong(startIp);
        const end = ipToLong(endIp);
        if (!cityIpRanges[city]) cityIpRanges[city] = [];
        cityIpRanges[city].push({start, end});
    })
    return cityIpRanges;
}

function matchCities(ipPool, queryIPs) {
    const cityIpRanges = parseIpPool(ipPool);
    return queryIPs.split(',').map(ip => {
        const ipNum = ipToLong(ip);
        let bestMatchCity = '';
        let smallestRange = Infinity;
        for(const city in cityIpRanges) {
            cityIpRanges[city].forEach(range => {
                if (ipNum >= range.start && ipNum <= range.end) {
                    const rangeSize = range.end - range.start;
                    if (rangeSize < smallestRange) {
                        bestMatchCity = city;
                        smallestRange = rangeSize;
                    }
                }
            })
        }
        return bestMatchCity;
    }).join(',');
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51