11
\$\begingroup\$

The task is simple, given two IP adresses a and b, output all addresses within that range.


Examples

Example #1:

f(a = 192.168.0.1, b = 192.168.0.4) 
    192.168.0.1
    192.168.0.2
    192.168.0.3
    192.168.0.4

Example #2 (TIO will truncate this, use a smaller range when testing):

f (a = 123.0.200.0, b = 124.0.0.0)
    123.0.200.0
    123.0.200.1
    ...            # Omitted pattern 
    123.0.200.255
    123.0.201.0
    ...            # Omitted pattern
    123.0.201.255
    ...            # Omitted pattern
    123.0.255.255
    123.1.0.0
    ...            # Omitted pattern
    123.255.255.255
    124.0.0.0

Input and Output

  • a < b in other words:
    • Defined Programatically: a[0] < b[0] || (a[0] == b[0] && a[1] < b[1]) || (a[0:1] == b[0:1] && a[2] < b[2]) || (a[0:2] == b[0:2] && a[3] < b[3])
    • Defined in Words: a will always be lower than b (so you will have to increment the subnet to reach b).
    • No, you do not have to handle a == b (if you do, kudos).
  • Output should be in order from "lowest" to "highest" (see examples).
  • For this challenge, the valid syntax for an IP is: \d{1-3}\.\d{1-3}\.\d{1-3}\.\d{1-3}.
  • You do not have to handle non-IP address input, if it's unexpected input you may error.
  • Output may be as an array or as a delimited string (using any whitespace character).

Winning

\$\endgroup\$
  • 1
    \$\begingroup\$ You have "Omitted Pattern" between e.g. 123.0.200.255 and 123.0.201.0, but aren't they sequential? \$\endgroup\$ – nmjcman101 Jun 5 '17 at 19:18
  • \$\begingroup\$ @nmjcman101 did that twice, fixed. \$\endgroup\$ – Magic Octopus Urn Jun 5 '17 at 19:36
3
\$\begingroup\$

Pyth, 22

mj\.jd256}FmivMcd\.256

Try it online.

               cd\.       # split string by "."
             vM           # eval list (convert strings to integers)
            i      256    # convert list of base256 digits to integer
           m          Q   # map the above over implicit input list
         }F               # inclusive range
    jd256                 # convert to list of base256 digits
 j\.                      # join by "." 
m                         # map over inclusive range 
\$\endgroup\$
  • 1
    \$\begingroup\$ This inspired a change to Pyth that should make such code shorter in the future. vM will be the default for v when applied to a list. \$\endgroup\$ – isaacg Jun 6 '17 at 2:27
  • \$\begingroup\$ @isaacg cool - thanks, I'll try to remember that for next time. \$\endgroup\$ – Digital Trauma Jun 6 '17 at 5:09
3
\$\begingroup\$

Batch, 623 bytes

@echo off
set s=%1.%2
call:c %s:.= %
exit/b
:c
if %1==%5 goto d
call:d %1 %2 %3 %4 %1 255 255 255
set/al=%1+1,u=%5-1
for /l %%i in (%l%,1,%u%)do call:d %%i 0 0 0 %%i 255 255 255
call:d %5 0 0 0 %5 %6 %7 %8
exit/b
:d
if %2==%6 goto e
call:e %1 %2 %3 %4 %1 %2 255 255
set/al=%2+1,u=%6-1
for /l %%j in (%l%,1,%u%)do call:e %1 %%j 0 0 %5 %%j 255 255
call:e %5 %6 0 0 %5 %6 %7 %8
exit/b
:e
if %3==%7 goto f
call:f %1 %2 %3 %4 %1 %2 %3 255
set/al=%3+1,u=%7-1
for /l %%k in (%l%,1,%u%)do call:e %1 %2 %%k 0 %5 %6 %%k 255
call:e %5 %6 %7 0 %5 %6 %7 %8
exit/b
:f
for /l %%l in (%4,1,%8)do echo %1.%2.%3.%%l

Unfortunately Batch's 32-bit arithmetic can't print all IP addresses, so I have to split it up into octets.

\$\endgroup\$
  • \$\begingroup\$ Is removing the @echo off an option? Not that it makes a huge difference. \$\endgroup\$ – Digital Trauma Jun 6 '17 at 5:21
  • \$\begingroup\$ @DigitalTrauma I guess it's not strictly necessary as the echo always goes to the console and so isn't part of STDOUT but it's very annoying especially on long scripts such as this one. \$\endgroup\$ – Neil Jun 6 '17 at 7:47
2
\$\begingroup\$

Python 2, 128 bytes

a,b=[reduce(lambda a,b:a<<8|int(b),x.split('.'),0)for x in input()]
while a<=b:print'.'.join(`a>>i&255`for i in[24,16,8,0]);a+=1

Try it online!

\$\endgroup\$
2
\$\begingroup\$

PHP, 71 Bytes

Output as string

for($s=ip2long($argv[1]);$s<=ip2long($argv[2]);)echo long2ip($s++)," ";

Try it online! or Output as array

print_r(array_map(long2ip,range(ip2long($argv[1]),ip2long($argv[2]))));

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Jelly, 18 bytes

ṣ”.V€ḅ⁹µ€r/b⁹j”.$€

Try it online!

The output appears to by a mush of digits and decimals, but is stored internally as a list of strings. Append a Y to the end (+1 byte) to join the strings by newlines.

How it Works

ṣ”.V€ḅ⁹µ€r/b⁹j”.$€ - main link, input is a list of addresses which are strings
       µ€          - for each address string,
ṣ”.                  - split on periods
   V€                - eval each element in the list (convert strings to numbers)
     ḅ⁹              - transform from base 256 to integer (⁹ is 256)
         r/        - take the inclusive range
           b⁹      - convert each element in the range from integer to base 256
             j”.$€ - join each address with periods.
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6), 104 bytes

g=s=>s.replace(/(\d+)\.256/,(_,n)=>++n+'.0')
f=(a,b)=>a==b?a:a+`
`+f(g(g(g(g(a+'.256').slice(0,-2)))),b)

This solution replaces the pattern n.256 with n+1.0, and it calls itself recursively until the two parameters are equal.

It appends '.256' to the initial input to get the ball rolling. slice(0,-2) is then used to remove the trailing '.0'.

Examples:

g=s=>s.replace(/(\d+)\.256/,(_,n)=>++n+'.0')
f=(a,b)=>a==b?a:a+`
`+f(g(g(g(g(a+'.256').slice(0,-2)))),b)

console.log('192.168.0.1 ... 192.168.0.4');
console.log(f('192.168.0.1', '192.168.0.4'));

console.log('123.255.255.0 ... 124.0.3.0');
console.log(f('123.255.255.0', '124.0.3.0'));

console.log('192.1.1.1 ... 192.1.1.1 ... kudos');
console.log(f('192.1.1.1', '192.1.1.1'));

\$\endgroup\$
1
\$\begingroup\$

Java (OpenJDK 8), 339 314 282 bytes

Golfed:

long f(String i)throws Exception{return java.nio.ByteBuffer.wrap(java.net.InetAddress.getByName(i).getAddress()).getInt()&(1L<<32)-1;}void g(String[] a)throws Exception{for(long l=f(a[0]),m=255;l<=f(a[1]);)System.out.println(((l>>24)&m)+"."+((l>>16)&m)+"."+((l>>8)&m)+"."+(l++&m));}

Ungolfed:

long ipToLong(String ip) throws Exception {
    return java.nio.ByteBuffer.wrap(java.net.InetAddress.getByName(ip).getAddress()).getInt() & (1L << 32) - 1;
}

void printRange(String[] ips) throws Exception {
    for (long ip = ipToLong(ips[0]), m = 255; ip <= ipToLong(ips[1]);)
        System.out.println(((ip >> 24) & m) + "." + ((ip >> 16) & m) + "." + ((ip >> 8) & m) + "." + (ip++ & m));
}

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.