7
\$\begingroup\$

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.
\$\endgroup\$
  • \$\begingroup\$ May we take negative integers in the format _# instead of -#, i.e. _37 instead of -37? \$\endgroup\$ – R. Kap Jan 15 '17 at 20:47
  • \$\begingroup\$ Yes. As I stated, input and output can be flexible. \$\endgroup\$ – Julian Lachniet Jan 15 '17 at 22:55
  • 3
    \$\begingroup\$ Shame about not using built-ins. Python3's module antigravity would have works well hg.python.org/cpython/file/tip/Lib/antigravity.py \$\endgroup\$ – george Jan 16 '17 at 10:51
  • \$\begingroup\$ @george Did you make that module? \$\endgroup\$ – Julian Lachniet Jan 16 '17 at 16:27
  • \$\begingroup\$ @JulianLachniet Unfortunately not, never actually had a use for it though \$\endgroup\$ – george Jan 16 '17 at 16:42
0
\$\begingroup\$

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.

\$\endgroup\$
5
\$\begingroup\$

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())

\$\endgroup\$
  • 2
    \$\begingroup\$ BTW in python3 geohash is in the stdlib:from antigravity import geohash \$\endgroup\$ – pgy Jan 23 '17 at 20:36
0
\$\begingroup\$

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
}
\$\endgroup\$
  • 1
    \$\begingroup\$ tio.run/nexus/groovy btw ;). \$\endgroup\$ – Magic Octopus Urn Jan 17 '17 at 20:52
  • \$\begingroup\$ Also, ` as String` is shorter than .toString() by one byte. \$\endgroup\$ – Magic Octopus Urn Jan 17 '17 at 20:54
  • \$\begingroup\$ @carusocomputing Thanks saved a lot by using this instead ""+... \$\endgroup\$ – Gurupad Mamadapur Jan 17 '17 at 21:37
  • 1
    \$\begingroup\$ Oh jeez! I shoulda seen that as well, haha that took it even further, nice one ☺. \$\endgroup\$ – Magic Octopus Urn Jan 17 '17 at 21:50

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.