On 9/14/07, Ruby Quiz <james / grayproductions.net> wrote:
> This week's Ruby Quiz is to write a simple utility.  Your program should accept
> an IP address as a command-line argument and print out the two letter code for
> the country that IP is assigned in.  You can find a database for the matching
> at:
>
>         http://software77.net/cgi-bin/ip-country/geo-ip.pl
>
> To keep the problem interesting though, let's write our programs with a focus on
> speed and memory efficiency.

Hi All,

Here's my submission.  It's almost exactly the same as Jesus'.   I have a feeling everyone is going to have very similar code for this one.

http://pastie.caboo.se/97332
os = ARGV[0].split(/\./)
ip = os[3].to_i + os[2].to_i*256 + os[1].to_i*256**2 + os[0].to_i*256**3

f = File.open("IpToCountry.csv")

# perform binary search on the file
low = 0
high = f.stat.size

while low <= high
  mid = (low + high) / 2

  f.seek mid  # seek to the middle of our search window
  f.seek -2, IO::SEEK_CUR  until f.getc == ?\n  # walk backwards until we hit a newline

  new_high = f.pos - 1
  line = f.gets
  new_low = f.pos

  from, to, x, x, country = line[1..-1].split(/","/)

  if to.to_i < ip  # we are too low, set new low to after this line
    low = new_low
  elsif from.to_i > ip  # we are too high, set new high to before the last newline
    high = new_high
  else
    puts country; exit
  end
end

puts "no country"- steve