# Given the names of two planets, give the distance

Using the following table (source) write some code that takes the names of two planets and returns the distance between them:

+-------------------+---------------+
|      Planets      | Distance (km) |
+-------------------+---------------+
| Mercury -> Venus  |      50290000 |
| Venus -> Earth    |      41400000 |
| Earth -> Mars     |      78340000 |
| Mars -> Jupiter   |     550390000 |
| Jupiter -> Saturn |     646270000 |
| Saturn -> Uranus  |    1448950000 |
| Uranus -> Neptune |    1627450000 |
| Neptune -> Pluto  |    1405380000 |
+-------------------+---------------+

Examples, input then output:

Mercury, Mars
170030000
Neptune, Jupiter
-3722670000
Earth, Earth
0

Note the negative sign there, as Jupiter comes before Neptune. They are also all integers.

Pluto doesn't have to be included (mostly because of a weird orbit which makes it hard to work out the distance - that distance given is my own calculation, but as Pluto is all famous now...).

By distances between planets I'm meaning orbits - I don't expect a date and working out where they are.

This is code golf, shortest code wins.

• +1 for not "coz Pluto ain't a planet" Jul 15 '15 at 16:04
• @Optimizer I'm doing a project which needs the distances and nobody can agree! I resorted to using it's orbital period and orbital speed...
– Tim
Jul 15 '15 at 16:04
• Can our function/program return a float? i.e. Mercury, Mars -> 170030000.0?
Jul 15 '15 at 16:06
• It's implied, but are we assuming the holy moment in time where the planets are all in a straight line and the distance between any two non-adjacent planets is the sum of distances in between? Jul 15 '15 at 16:10
• Is there a penalty for including Pluto (besides the bytes)? I feel kinda bad for it, it just had it's big day and all... Jul 15 '15 at 16:23

# CJam, 5451 44 bytes

2{"X84VT:Z/3KD'Y->>6\ Ta "3/r26b93%=70be4}*-

Try it online in the CJam interpreter.

### Idea

We use a simple hashing function to identify all eight planets. By considering each name as the array of its code points, converting them from base 26 to integer and taking the result modulo 93 then modulo 8, Mercury, Venus, Earth, etc. map to 2, 4, 0, 1, 3, 5, 6 and 7.

Now, we choose a point that lies 320,000 km behind Neptune and calculate the distances of all eight planets to that point. After dropping four trailing zeroes and reordering the planets so that they fit the 8 indexes from above, we obtain the array

[435172 427338 444341 372299 439312 307672 162777 32]

which, if we encode each integer in base 70, yields the following:

[
[1 18 56 52] [1 17 14 58] [1 20 47 51] [1 5 68 39]
[1 19 45 62] [  62 55 22] [  33 15 27] [       32]
]

Remembering that two adjacent digits (A B) can be replaced with ((A-1) (B+70)), we can modify the array from above so that all integers can be encoded as printable ASCII characters:

["X84" "VT:" "Z/3" "KD'" "Y->" ">6\\" " Ta" " "]

### Code

2{                         e# Do twice:
"X84VT:Z/3KD'Y->>6\ Ta " e#   Push that string.
3/                       e#   Chop it into chunks of length 3.
r                        e#   Read a token from STDIN.
26b                      e#   Convert from base 26 to integer.
93%                      e#   Take the result modulo 93.
=                        e#   Retrieve the chunk at that index.
70b                      e#   Convert from base 70 to integer.
e4                       e#   Multiply by 10,000.
}*                         e#
-                          e# Subtract the two results.

# Python 2, 149147142138128123 119 Bytes

Just uses a simple lookup to figure out which distances to use :) This defines an anonymous function, so to use it you'll need to give it a name.

Thanks to Sp3000 for ideas that saved a bunch of bytes!

lambda*x:int.__sub__(*[[0,5029,9169,17003,72042,136669,281564,444309]['MeVeEaMaJuSaUr'.find(k[:2])/2]for k in x])*~9999

Indented properly and ungolfed slightly for readability:

def f(*x):
d=0,5029,9169,17003,72042,136669,281564,444309
a,b=[d['MeVeEaMaJuSaUr'.find(k[:2])/2]for k in x]
print(b-a)*10000

Call like so:

f("Mercury","Mars")    -> 170030000
f("Neptune","Jupiter") -> -3722670000L
• Your output is missing a 0, but you seem to be multiplying by the right amount.
– Tim
Jul 15 '15 at 16:31
• @Tim I messed up in the example call, it does have a fourth 0 at the end :P
Jul 15 '15 at 16:32
• You are forgetting pluto?
– Will
Jul 15 '15 at 20:08
• @Will Pluto doesn't have to be included...
Jul 15 '15 at 20:09
• (You'll save at least two bytes if you copy that find returning -1 trick from my entry, and then you'll pull ahead of me :)
– Will
Jul 15 '15 at 20:28

# Prolog, 190174 151 bytes

Thanks to Fatalize for guidance.

g(A,X):-sub_atom(A,2,2,_,B),member(B:X,[rc:0,nu:5029,rt:9169,rs:17003,pi:72042,tu:136669,an:281564,pt:444309]).
s(A,B,R):-g(A,X),g(B,Y),R is(Y-X)*10^4.

170030000

# Pyth - 59 53 bytes

Encodes the distance in unicode codepoints.

-Fm*^T4s<CM"Ꭵာẚ훿ﱳ𣗿𧮹"x"MshrJtaN"@d14_Q

The name lookup is kinda cool because it loops around. Thanks to @Dennis for suggesting index 14 as a collision free lookup!

• I used index 14 in my first revision. It is collision-free. Jul 16 '15 at 2:37

# Bash, 140 bytes

bc<<<"(-sed -e 's/,/+/;s/[abd-z]//g;s/Mc/0/g;s/V/5029/g;s/E/9169/g;s/M/17003/g;s/J/72042/g;s/S/136669/g;s/U/281564/g;s/N/444309/g')*10^4"

$bash script.sh Mercury, Mars 170030000$ bash script.sh
Neptune, Jupiter
-3722670000
$bash script.sh Earth, Earth 0 ## CoffeeScript, 183 180 bytes f=(a,b)->t=[d=0,5029,4140,7834,55039,64627,144895,162745];n='MeVeEaMaJuSaUrNe';t=(x=n[q='indexOf'](a[..1])/2)<(y=n[q](b[..1])/2)&&t[x+1..y]||t[y+1..x];d+=c*1e4for c in t;x>y&&-d||d Unminified: f = (a,b) -> t = [d = 0, 5029, 4140, 7834, 55039, 64627, 144895, 162745] n = 'MeVeEaMaJuSaUrNe' t = if (x = n[q='indexOf'](a[..1]) / 2) < (y = n[q](b[..1]) / 2) then t[x+1..y] else t[y+1..x]; d += c * 1e4 for c in t if x > y then -d else d # Ruby, 168 bytes a=ARGV.map{|e|e=='Mars'?3:%w(M V E m J S U N P).index(e[0])} p 10000*(a[1]<=>a[0])*[5029,4140,7834,55039,64627,144895,162745,140538][a.min..a.max-1].inject(0){|r,e|r+e} It's designed as a script to be run from command line, thus uses ARGV. Run as$ ruby planets.rb Mercury Mars
170030000
$ruby planets.rb Neptune Jupiter -3722670000$ ruby planets.rb Earth Earth
0
$ruby planets.rb Mercury Venus 50290000$ ruby planets.rb Venus Earth
41400000
$ruby planets.rb Mercury Mercury 0$ ruby planets.rb Pluto Pluto
0
$ruby planets.rb Mercury Pluto 5848470000$ ruby planets.rb Pluto Mercury
-5848470000

data P=Mercury|Venus|Earth|Mars|Jupiter|Saturn|Uranus|Neptune deriving Enum
x#y=(d y-d x)*10^4

Usage example:

*Main> Neptune # Jupiter
-3722670000

*Main> Mercury # Mars
170030000

How it works: I define a new data type P where the constructor names are the names of the planets. I also put it in the Enum class, i.e. I get a mapping to integers via fromEnum (in order of definition, starting with Mercury -> 0). This integer can be used as a index for the distance list.

Edit: @Kritzefitz found two bytes to save and @Alchymist another one. Thanks!

• You can remove the parentheses around fromEnum x and save two bytes. Jul 15 '15 at 21:26
• Can you use 10^4 instead of 10000 or will that affect the output? Jul 16 '15 at 14:54
• @Alchymist: yes, it's possible. Thanks!
– nimi
Jul 16 '15 at 18:01

# Julia, 206203 190 bytes

(f,t)->t==f?0:(M(p)=p=="Mars"?4:findin("MVEmJSUN",p[1])[1];T=M(t);F=M(f);(T>F?1:-1)*sum([get(Dict(zip(1:8,[5029,4140,7834,55039,64627,144895,162745,0])),i,0)for i=T>F?(F:T-1):(T:F+1)])*1000)

This creates an unnamed function that accepts two strings and returns an integer. To call it, give it a name.

Ungolfed + explanation:

function planet_distance(p_from, p_to)
if p_from == p_to
# Return 0 right away if we aren't going anywhere
0
else
# Define a function to get the planet's order in the solar system
M(p) = p == "Mars" ? 4 : findin("MVEmJSUN", p[1])[1]

# Get indices for origin and destination
ind_from = M(p_from)
ind_to = M(p_to)

# Define a dictionary to look up distances by index
D = Dict(zip(1:8,[5029,4140,7834,55039,64627,144895,162745,0])

# Determine whether the distance will be positive or negative
# and the range over which we'll sum distances
if ind_to > ind_from
coef = 1
range = ind_from:ind_to-1
else
coef = -1
range = ind_to:ind_from+1
end

# Sum the distances between points
coef * sum([get(D, i, 0) for i in range]) * 1000
end
end

# Java, 257 228 bytes

enum Z{Mercury(0),Venus(5029),Earth(9169),Mars(17003),Jupiter(72042),Saturn(136669),Uranus(281564),Neptune(444309),Pluto(584847);long r;Z(long x){r=x*10000;}static long d(String...s){return Z.valueOf(s[1]).r-Z.valueOf(s[0]).r;}}

static long d(String...s){...} solves the challenge. Input requires names of planets to match the enum's constants' names exactly. I love how java provides a string to enum conversion method for me <3

Usage:

Z.d("Mercury","Pluto") returns 5848470000

Z.d("Pluto","Mercury") returns -5848470000

Z.d("Uranus","Neptune") returns 1627450000

Z.d("Mars","Pluto") returns 5678440000

char*p="(3$,?2'+";D[]={0,5029,9169,17003,72042,136669,281564,444309,584847}; #define E(x)D[strchr(p,*x^x[1])-p] #define f(s,t)(E(t)-E(s))*10000LL Try it online! Another version, courtesy of ceilingcat, using Unicode, which seems to make TiO count weirdly: # C (gcc), 119 bytes char*p="(3$,?2'+";
#define E(x)L"\0Ꭵ⏑䉫𑥪𡗝񄯜񬞕򎲏"[index(p,*x^x[1])-p]
#define f(s,t)(E(t)-E(s))*10000LL

Try it online!