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.
- Format the date and Dow Opening in this structure:
YYYY-MM-DD-DOW. For example, it might look like2005年05月26日-10458.68. - 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:
db9318c2259923d0and8b672cb305440f97. - Append each string to
0.and convert to decimal. Using the above strings, we get the following:0.db9318c2259923d0and0.8b672cb305440f97, which is converted to decimal as aproximately0.8577132677070023444and0.5445430695592821056. You must truncate it down the the first 8 characters, producing0.857713and0.544543. - Combine the coordinates given through input and the decimals we just produced:
37+0.857713=37.857713and-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.
5 Answers 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())
-
2\$\begingroup\$ BTW in python3 geohash is in the stdlib:
from antigravity import geohash\$\endgroup\$pgy– pgy2017年01月23日 20:36:57 +00:00Commented Jan 23, 2017 at 20:36 -
\$\begingroup\$
float.fromhexcan be.0.fromhex\$\endgroup\$pxeger– pxeger2021年12月18日 01:54:04 +00:00Commented Dec 18, 2021 at 1:54
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;}
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.
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]
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
}
-
1\$\begingroup\$ tio.run/nexus/groovy btw ;). \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2017年01月17日 20:52:17 +00:00Commented Jan 17, 2017 at 20:52
-
1\$\begingroup\$ Also, ` as String` is shorter than
.toString()by one byte. \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2017年01月17日 20:54:10 +00:00Commented Jan 17, 2017 at 20:54 -
\$\begingroup\$ @carusocomputing Thanks saved a lot by using this instead
""+... \$\endgroup\$Gurupad Mamadapur– Gurupad Mamadapur2017年01月17日 21:37:23 +00:00Commented 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\$Magic Octopus Urn– Magic Octopus Urn2017年01月17日 21:50:09 +00:00Commented Jan 17, 2017 at 21:50
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 ]
```
-
\$\begingroup\$ Save 3 bytes with
d+-o. \$\endgroup\$Shaggy– Shaggy2023年08月23日 08:49:05 +00:00Commented Aug 23, 2023 at 8:49 -
\$\begingroup\$ Oh, nice one :) \$\endgroup\$Steve Bennett– Steve Bennett2023年08月23日 13:00:43 +00:00Commented Aug 23, 2023 at 13:00
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])
Hashlib stole my bytes, :P.
-
1\$\begingroup\$ I can recover those bytes, but you’ll need to pay a £10.00 fee. \$\endgroup\$The Empty String Photographer– The Empty String Photographer2023年11月12日 13:53:08 +00:00Commented Nov 12, 2023 at 13:53
_#instead of-#, i.e._37instead of-37? \$\endgroup\$