Geohash Generator

7

2

XKCD Comic:enter image description here


Goal:

Given a date, the current Dow Opening, and your current coordinates as a rounded integer, produce a "geohash."

Input:

Input through any reasonable means (STDIN, function argument, flag, etc.) the following:

  • The current date. This does necessarily have to be the date of the system's clock, so assume that the input is correct.
  • The most recent Dow Opening (must support at least 2 decimal places)
  • The floor of your current latitude and longitude.

To make input easier, you can input through any reasonable structured format. Here are some examples (you may create your own):

["2005","05","26","10458.68","37",-122"]
2005-05-26,10458.68,37,-122
05-26-05 10458.68 37 -122

Algorithm:

Given your arguments, you must perform the "geohash" algorithm illustrated in the comic. The algorithm is as follows.

  1. Format the date and Dow Opening in this structure: YYYY-MM-DD-DOW. For example, it might look like 2005-05-26-10458.68.
  2. Perform an md5 hash on the above. Remove any spacing or parsing characters, and split it in to two parts. For example, you might have these strings: db9318c2259923d0 and 8b672cb305440f97.
  3. Append each string to 0. and convert to decimal. Using the above strings, we get the following: 0.db9318c2259923d0 and 0.8b672cb305440f97, which is converted to decimal as aproximately 0.8577132677070023444 and 0.5445430695592821056. You must truncate it down the the first 8 characters, producing 0.857713 and 0.544543.
  4. Combine the coordinates given through input and the decimals we just produced: 37 + 0.857713 = 37.857713 and -122 + 0.544543 = -122.544543

Notes:

  • To prevent the code from being unbearably long, you may use a built-in for the md5 hash.
  • Standard loopholes (hardcoding, calling external resource) are forbidden.

Julian Lachniet

Posted 2017-01-15T14:02:21.327

Reputation: 3 216

May we take negative integers in the format _# instead of -#, i.e. _37 instead of -37? – R. Kap – 2017-01-15T20:47:10.477

Yes. As I stated, input and output can be flexible. – Julian Lachniet – 2017-01-15T22:55:13.707

3

Shame about not using built-ins. Python3's module antigravity would have works well https://hg.python.org/cpython/file/tip/Lib/antigravity.py

– george – 2017-01-16T10:51:56.213

@george Did you make that module? – Julian Lachniet – 2017-01-16T16:27:33.253

@JulianLachniet Unfortunately not, never actually had a use for it though – george – 2017-01-16T16:42:05.910

@george Considering that module was created the day I posted the challenge, I'm a little bit suspicious. – Julian Lachniet – 2017-01-16T16:48:11.037

@JulianLachniet That page was only updated on the 16th, not created luckily. I've know about the modules for a few years. https://www.explainxkcd.com/wiki/index.php/353:_Python suggests that is as old as 2.7.0, which was released in 2010. https://www.python.org/download/releases/2.7/

– george – 2017-01-16T17:10:29.280

@JulianLachniet That module has been around for a while. I used it in this answer more than a year ago (just to be funny, though.)

– mbomb007 – 2017-01-17T20:16:52.627

Answers

0

Bash + Coreutils + md5, 98 bytes:

C=`md5 -q -s $1-$2`;C=${C^^};for i in 3 4;{ dc -e 16i[${!i}]n`cut -c1-7<<<.${C:$[16*(i>3)]:16}`p;}

Try It Online!

Uses the built-in md5 command on OSX to generate the MD5 hash. Takes 4 space separated command line arguments in the following format:

YYYY-MM-DD DOW LAT LONG

with negative numbers input and output with a leading underscore (i.e. _122 instead of -122).

Note: Depending on your system, you may need to substitute in echo -n $1-$2|md5sum for md5 -q -s $1-$2 in order for this to work. Doing so brings the byte count up to 103, and is indeed the case in the TIO link.

R. Kap

Posted 2017-01-15T14:02:21.327

Reputation: 4 730

5

Python 2, 129 bytes

import md5
d,q,c=input()
h=md5.new(d+'-'+q).hexdigest()
print map(lambda p,o:o+'.'+`float.fromhex('.'+p)`[2:8],(h[:16],h[16:]),c)

Input is given in the form '2005-05-26','10458.68',('37','-122') (using the example).

Computes the MD5 hash with md5.new().hexdigest(), then performs the necessary transforms. I could save five bytes by using h instead of h[:16], but I'm not sure if that would affect the six most significant digits in the decimal conversion.

Ideone it! (substituting an eval() call for the input())

Copper

Posted 2017-01-15T14:02:21.327

Reputation: 3 684

2BTW in python3 geohash is in the stdlib:from antigravity import geohash – pgy – 2017-01-23T20:36:57.837

0

Groovy, 198 161 bytes

{d,o,l,L->m=""+MessageDigest.getInstance("MD5").digest((d+"-"+o).bytes).encodeHex()
h={(Double.valueOf("0x0."+it+"p0")+"")[1..7]}
[l+h(m[0..15]),L+h(m[16..31])]}

This is an unnamed closure.

Input
f("2005-05-26","10458.68","37","-122")

Output
[37.857713, -122.544543]

Try it here!

Ungolfed -

import java.security.*
{
    date,open,lat,lon ->
    md = "" + MessageDigest.getInstance("MD5").digest((date+"-"+open).bytes).encodeHex()
    decimal = {(Double.valueOf("0x0."+it+"p0")+"")[1..7]}
    [lat+decimal(md[0..15]),lon+decimal(md[16..31])]  //Implicity returns
}

Gurupad Mamadapur

Posted 2017-01-15T14:02:21.327

Reputation: 1 791

1https://tio.run/nexus/groovy btw ;). – Magic Octopus Urn – 2017-01-17T20:52:17.063

Also, as String is shorter than .toString() by one byte. – Magic Octopus Urn – 2017-01-17T20:54:10.067

@carusocomputing Thanks saved a lot by using this instead ""+... – Gurupad Mamadapur – 2017-01-17T21:37:23.323

1Oh jeez! I shoulda seen that as well, haha that took it even further, nice one ☺. – Magic Octopus Urn – 2017-01-17T21:50:09.060