10
\$\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.
asked Jan 15, 2017 at 14:02
\$\endgroup\$
8
  • \$\begingroup\$ May we take negative integers in the format _# instead of -#, i.e. _37 instead of -37? \$\endgroup\$ Commented Jan 15, 2017 at 20:47
  • \$\begingroup\$ Yes. As I stated, input and output can be flexible. \$\endgroup\$ Commented Jan 15, 2017 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\$ Commented Jan 16, 2017 at 10:51
  • \$\begingroup\$ @george Did you make that module? \$\endgroup\$ Commented Jan 16, 2017 at 16:27
  • \$\begingroup\$ @JulianLachniet Unfortunately not, never actually had a use for it though \$\endgroup\$ Commented Jan 16, 2017 at 16:42

5 Answers 5

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

answered Jan 15, 2017 at 16:35
\$\endgroup\$
2
  • 2
    \$\begingroup\$ BTW in python3 geohash is in the stdlib:from antigravity import geohash \$\endgroup\$ Commented Jan 23, 2017 at 20:36
  • \$\begingroup\$ float.fromhex can be .0.fromhex \$\endgroup\$ Commented Dec 18, 2021 at 1:54
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.

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

Javascript (Node, using built-in Crypto), 165 characters

(d,o,l)=>l.map((p,i)=>p+Math.sign(p)*[...require('crypto').createHash('md5').update(d+-o).digest`hex`.slice(z=i*16,z+16)]
.reduce((a,d,i)=>a+parseInt(d,16)*16**~i,0))

Such a verbose API!

JavaScript (using md5 library), 125 characters

(d,o,l)=>l.map((p,i)=>p+Math.sign(p)*[...require('md5')(d+-o).slice(z=i*16,z+16)]
.reduce((a,d,i)=>a+parseInt(d,16)*16**~i,0))

Nothing very golfy here.

In both cases:

f('2005-05-26', 10458.68, [144,-37])
=> [ 144.857713267707, -37.54454306955928 ]
```
answered Aug 23, 2023 at 7:08
\$\endgroup\$
2
  • \$\begingroup\$ Save 3 bytes with d+-o. \$\endgroup\$ Commented Aug 23, 2023 at 8:49
  • \$\begingroup\$ Oh, nice one :) \$\endgroup\$ Commented Aug 23, 2023 at 13:00
0
\$\begingroup\$

Python, 185 bytes

import hashlib as h
x,y,a,n=input().split(',')
b=h.md5((x+'-'+y).encode()).hexdigest()
q=list(map(str,map(float.fromhex,['0x.'+b[:15],'0x.'+b[16:]])))
print(a+q[0][1:8]+','+n+q[1][1:8])

Attempt This Online!

Hashlib stole my bytes, :P.

answered Nov 12, 2023 at 9:36
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I can recover those bytes, but you’ll need to pay a £10.00 fee. \$\endgroup\$ Commented Nov 12, 2023 at 13:53

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.