Étant donné les noms de deux planètes, donnez la distance

25

À l'aide du tableau suivant ( source ), écrivez du code qui prend les noms de deux planètes et renvoie la distance entre elles:

+-------------------+---------------+
|      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 |
+-------------------+---------------+

Exemples, entrée puis sortie:

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

Notez le signe négatif là-bas, car Jupiter précède Neptune. Ce sont aussi tous des entiers.

Pluton n'a pas à être inclus (principalement en raison d'une orbite étrange qui rend difficile la détermination de la distance - cette distance donnée est mon propre calcul, mais comme Pluton est désormais célèbre ...).

Par distances entre les planètes, je veux dire des orbites - je ne m'attends pas à une date et à savoir où elles sont.

C'est le golf de code, le code le plus court gagne.

Tim
la source
10
+1 pour pas "coz Pluton n'est pas une planète"
Optimizer
@Optimizer Je fais un projet qui a besoin des distances et personne ne peut être d'accord! J'ai eu recours à sa période orbitale et à sa vitesse orbitale ...
Tim
Notre fonction / programme peut-il retourner un flotteur? c'est à dire Mercury, Mars -> 170030000.0?
Kade
8
C'est implicite, mais supposons-nous le moment sacré dans le temps où les planètes sont toutes en ligne droite et la distance entre deux planètes non adjacentes est la somme des distances entre elles?
Sp3000
3
Y a-t-il une pénalité pour inclure Pluton (en plus des octets)? Je me sens un peu mal pour ça, il a juste eu son grand jour et tout ...
DeadChex

Réponses:

24

CJam, 54 51 44 octets

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

Essayez-le en ligne dans l' interpréteur CJam .

Idée

Nous utilisons une fonction de hachage simple pour identifier les huit planètes. En considérant chaque nom comme le tableau de ses points de code, en les convertissant de la base 26 en entier et en prenant le résultat modulo 93 puis modulo 8, Mercure , Vénus , Terre , etc. mapper en 2 , 4 , 0 , 1 , 3 , 5 , 6 et 7 .

Maintenant, nous choisissons un point situé à 320 000 km derrière Neptune et calculons les distances des huit planètes jusqu'à ce point. Après avoir laissé tomber quatre zéros à la fin et réorganisé les planètes pour qu'elles correspondent aux 8 index d'en haut, nous obtenons le tableau

[435172 427338 444341 372299 439312 307672 162777 32]

qui, si nous codons chaque entier en base 70, donne ce qui suit:

[
   [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]
]

En se rappelant que deux chiffres adjacents (A B)peuvent être remplacés par ((A-1) (B+70)), nous pouvons modifier le tableau ci-dessus afin que tous les entiers puissent être encodés en caractères ASCII imprimables:

["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.
Dennis
la source
10

Python 2, 149 147 142 138 128 123 119 Octets

Utilise simplement une simple recherche pour déterminer les distances à utiliser :) Cela définit une fonction anonyme, donc pour l'utiliser, vous devrez lui donner un nom.

Merci à Sp3000 pour les idées qui ont sauvé un tas d'octets!

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

Indenté correctement et légèrement non golfé pour plus de lisibilité:

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

Appelez comme ça:

f("Mercury","Mars")    -> 170030000
f("Neptune","Jupiter") -> -3722670000L
Kade
la source
Votre sortie manque un 0, mais vous semblez multiplier par la bonne quantité.
Tim
@Tim Je me suis trompé dans l'exemple d'appel, il a un quatrième 0 à la fin: P
Kade
Tu oublies Pluton?
Will
@Will Pluto n'a pas besoin d'être inclus ...
Kade
(Vous économiserez au moins deux octets si vous copiez cette trouvaille renvoyant -1 astuce de mon entrée, puis vous devancerez moi :)
Will
8

Prolog, 190 174 151 octets

Merci à Fatalize pour ses conseils.

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.

$ gprolog --consult-file src.pro 
| ?- s('Mercury','Mars',R).   
R = 170030000 ? 
yes
| ?- s('Neptune','Jupiter',R).
R = -3722670000 ? 
yes
| ?- s('Earth','Earth',R).    
R = 0 ? 
yes
SteelRaven
la source
Pourquoi ne renvoyez-vous pas ce résultat directement comme ceci s(A, B, R)au lieu d'écrire R? Rien n'est spécifié pour les sorties, donc un retour de prédicat devrait convenir.
Fatalize
Vous pouvez également rasera 22 octets en modifiant prédicat gpour 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]).et supprimer tous les faits pour les planètes. C'est moins cool que =..mais il est plus court pour obtenir un mappage de valeur-clé
Fatalize
7

JavaScript (ES6), 115 110 bytes

(x,y,g=k=>"Me0Ve5029Ea9169Ma17003Ju72042Sa136669Ur281564Ne444309".match(k[0]+k[1]+"(\\d*)")[1]*1e4)=>g(y)-g(x)

Il s'agit d'une fonction anonyme, vous devrez donc la stocker dans une variable ( f=...; f("Earth", "Mercury")) ou l'utiliser comme expression entre parenthèses ( (...)("Earth", "Mercury").

Cette chaîne en désordre est les deux premières lettres de chaque planète, suivies de la distance de cette planète à Mercure (divisée par 10000, pour économiser de l'espace). La fonction intérieure gfait ce qui suit:

  1. prend un nom ( k),
  2. le réduit aux deux premières lettres ( k[0]+k[1]),
  3. utilise une correspondance d'expression régulière pour trouver la distance correspondante de Mercure, divisée par 10000 (par exemple, l'expression régulière "Terre" ressemble Ea(\d*)),
  4. multiplie la valeur par 10000 (1e4 ) et renvoie le résultat.

En soustrayant une distance de Mercure de l'autre, nous obtenons la distance entre les planètes.

absides
la source
@ vihan1086 Aha, j'ai fait l'erreur classique de confondre la valeur du point de code avec la représentation réelle des octets :(
apsillers
1
UTF-8 est juste le mauvais encodage pour cette astuce. Tous les caractères renvoyés par btoaont des points de code inférieurs à 256, donc ISO 8859-1 codera chaque caractère en utilisant un seul octet.
Dennis
7

Java, 274 272 264 octets (inclut Pluton!)

  void p(String p,String l){String q="MeVeEaMaJuSaUrNePl";int w=q.indexOf(p.substring(0,2))/2,e=q.indexOf(l.substring(0,2))/2,m=1,t=e,d[]={5029,4140,7834,55039,64627,144895,162745,140538};long h=0;if(w>e){e=w;w=t;m=-1;}for(;e-->w;)h+=d[e]*1e4;System.out.print(h*m);}

Entrée sortie:

p("Mercury","Mars") --> 170030000
p("Mars","Mercury") --> -170030000
p("Earth","Earth")  --> 0

Espacé et tabulé:

void p(String p,String l){
    String q="MeVeEaMaJuSaUrNePl";
    int w=q.indexOf(p.substring(0,2))/2,
      e=q.indexOf(l.substring(0,2))/2,
      m=1,
      t=e,
      d[]={5029,4140,7834,55039,64627,144895,162745,140538};
    long h=0;
    if(w>e){
        e=w;
        w=t;
        m=-1;
    }
    for(;e-->w;)
        h+=d[e]*1e4;
    System.out.print(h*m);
}
DeadChex
la source
1
Vous pouvez couper beaucoup en divisant tous les nombres par 1000
Tim
Je suis sur le point de faire ça!
DeadChex
1
Vous pouvez également mettre les déclarations intet int[]sur une seule ligne si le tableau vient en dernier: Likeint i=0,j=1,k[]={};
Geobits
1
Vous pouvez raser deux octets en remplaçant 10000par 1e4.
Anubian Noob
1
puisque nous savons que e > wvous pouvez couper un caractère en utilisant l'opérateur va à: while(e-->w)qui est de 12 caractères, au lieu de for(;e--!=w;)13.
corsiKa
6

Python, 118 octets

n=lambda x:(5029,9169,17003,72042,136669,281564,444309,0)["VeEaMaJuSaUrNe".find(x[:2])/2]*10000
f=lambda a,b:n(b)-n(a)

n est une fonction qui renvoie la distance de Mercure.

La chaîne "VeEaMaJuSaUrNe"est les deux premiers caractères de tous les noms de planète sauf Mercure . findne peut pas trouver Mercure et retournera donc -1. -1/2 est toujours -1 donc c'est le dernier élément du tuple, qui est 0.

Code de test simple:

test = (
    ("Mercury","Venus",50290000),
    ("Venus","Earth",41400000),
    ("Earth","Mars",78340000),
    ("Mars","Jupiter",550390000),
    ("Jupiter","Saturn",646270000),
    ("Saturn","Uranus",1448950000),
    ("Uranus","Neptune",1627450000),
    #("Neptune","Pluto",1405380000),
    ("Mercury","Mars",170030000),
    ("Neptune","Jupiter",-3722670000),
    ("Earth","Earth",0))

for a, b, expect in test:
    print a, "->", b, "=", expect
    assert f(a, b) == expect, f(a, b)
Volonté
la source
Belle astuce là-bas.
Anubian Noob
6

APL, 97 95 85 octets

{1E4×-/(0 5029 9169 17003 72042 136669 281564 444309[{⍵≡'Mars':4⋄'MVEmJSUN'⍳⊃⍵}¨⍵⍺])}

Cela crée une fonction dyadique sans nom qui prend la planète d'origine comme argument de gauche et la planète de destination comme droite.

Vous pouvez l' essayer en ligne !

Alex A.
la source
4

J-- , 226 octets

main {str q = "MeVeEaMaJuSaUrNePl"; int w = q.indexOf (a [0] .subs (0,2)) / 2, e = q.indexOf (a [1] .subs (0,2)) / 2, m = 1, t = e, d [] = {5029,4140,7834,55039,64627,144895,162745,140538}; lg h = 0; @i (w> e) {e = w; w = t; m = -1;} @ f (; e - ^^ w;) h + = d [e] * 10000; echo (h * m);}

Je ne pense pas que cela compte car je faisais le langage pendant que la question était en suspens, mais c'était surtout un test de la façon dont je pouvais compresser le code Java. Ceci est totalement et complètement basé sur la réponse de DeadChex .

Voici comment l'utiliser:

$ j-- planets.j-- Mercure Mars
170030000
phase
la source
4

Pyth - 59 53 octets

Encode la distance en points de code unicode.

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

La recherche de nom est plutôt cool car elle tourne en boucle. Merci à @Dennis d'avoir suggéré l'index 14 comme recherche sans collision!

Essayez-le ici en ligne .

Maltysen
la source
J'ai utilisé l'index 14 dans ma première révision. Il est sans collision.
Dennis
3

Bash, 140 octets

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
SteelRaven
la source
3

CoffeeScript, 183 180 octets

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

Non minifié:

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
rink.attendant.6
la source
3

Rubis, 168 octets

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}

Il est conçu comme un script à exécuter à partir de la ligne de commande, donc utilise ARGV. Courir comme

$ 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
Karsten S.
la source
3

Haskell, 160 158 157 octets

data P=Mercury|Venus|Earth|Mars|Jupiter|Saturn|Uranus|Neptune deriving Enum
d x=[0,5029,9169,17003,72042,136669,281564,444309]!!fromEnum x
x#y=(d y-d x)*10^4

Exemple d'utilisation:

*Main> Neptune # Jupiter
-3722670000

*Main> Mercury # Mars
170030000

Comment ça marche: je définis un nouveau type de données Poù les noms des constructeurs sont les noms des planètes. Je l'ai également mis dans la Enumclasse, c'est-à-dire que j'obtiens un mappage aux entiers via fromEnum(dans l'ordre de définition, en commençant par Mercury-> 0). Cet entier peut être utilisé comme index pour la liste des distances.

Edit: @Kritzefitz a trouvé deux octets à enregistrer et @Alchymist un autre. Merci!

nimi
la source
Vous pouvez supprimer les parenthèses autour fromEnum xet enregistrer deux octets.
Kritzefitz
Pouvez-vous utiliser 10 ^ 4 au lieu de 10000 ou cela affectera-t-il la sortie?
Alchymist
@Alchymist: oui, c'est possible. Merci!
nimi
2

Julia, 206 203 190 octets

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

Cela crée une fonction sans nom qui accepte deux chaînes et renvoie un entier. Pour l'appeler, donnez-lui un nom.

Non golfé + explication:

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
Alex A.
la source
2

Java, 257 228 octets

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){...}résout le défi. L'entrée requiert des noms de planètes correspondant exactement aux noms des constantes de l'énumération. J'adore la façon dont java fournit une méthode de conversion chaîne en énumération pour moi <3

Usage:

Z.d("Mercury","Pluto") résultats 5848470000

Z.d("Pluto","Mercury") résultats -5848470000

Z.d("Uranus","Neptune") résultats 1627450000

Z.d("Mars","Pluto") résultats 5678440000

Jack Ammo
la source
1

Macro préprocesseur C (gcc) , 146 octets

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

Essayez-le en ligne!

gastropner
la source