Geben Sie bei den Namen zweier Planeten die Entfernung an

25

Verwenden Sie die folgende Tabelle ( Quelle ), um Code zu schreiben, der die Namen zweier Planeten aufnimmt und den Abstand zwischen ihnen zurückgibt:

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

Beispiele, Eingabe dann Ausgabe:

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

Beachten Sie das negative Vorzeichen, da Jupiter vor Neptun steht. Sie sind auch alle ganzen Zahlen.

Pluto muss nicht enthalten sein (hauptsächlich wegen einer seltsamen Umlaufbahn, die es schwierig macht, die Entfernung zu berechnen - diese Entfernung ist meine eigene Berechnung, aber da Pluto jetzt alle berühmt ist ...).

Mit Entfernungen zwischen Planeten meine ich Umlaufbahnen - ich erwarte kein Datum und rechne nicht damit, wo sie sich befinden.

Dies ist Code Golf, der kürzeste Code gewinnt.

Tim
quelle
10
+1 für nicht "Coz Pluto ist kein Planet"
Optimierer
@Optimizer Ich mache ein Projekt, das die Entfernungen benötigt und dem niemand zustimmen kann! Ich habe auf die Umlaufzeit und die Umlaufgeschwindigkeit zurückgegriffen ...
Tim
Kann unsere Funktion / unser Programm einen Float zurückgeben? dh Mercury, Mars -> 170030000.0?
Kade
8
Es ist impliziert, aber nehmen wir den heiligen Moment in der Zeit an, in dem die Planeten alle auf einer geraden Linie liegen und der Abstand zwischen zwei nicht benachbarten Planeten die Summe der Abstände zwischen ihnen ist?
Sp3000,
3
Gibt es eine Strafe für das Einschließen von Pluto (neben den Bytes)? Ich fühle mich irgendwie schlecht dafür, es war gerade ein großer Tag und alles ...
DeadChex

Antworten:

24

CJam, 54 51 44 Bytes

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

Probieren Sie es online im CJam-Interpreter aus .

Idee

Wir verwenden eine einfache Hash-Funktion, um alle acht Planeten zu identifizieren. Indem Sie jeden Namen als Array seiner Codepunkte betrachten, ihn von der Basis 26 in eine Ganzzahl umwandeln und das Ergebnis modulo 93 nehmen, ordnen Sie dann modulo 8, Merkur , Venus , Erde usw. 2 , 4 , 0 , 1 , 3 , 5 zu , 6 und 7 .

Nun wählen wir einen Punkt, der 320.000 km hinter Neptun liegt und berechnen die Entfernungen aller acht Planeten zu diesem Punkt. Nachdem wir vier nachgestellte Nullen gelöscht und die Planeten so neu angeordnet haben, dass sie den 8 Indizes von oben entsprechen, erhalten wir das Array

[435172 427338 444341 372299 439312 307672 162777 32]

was, wenn wir jede ganze Zahl in der Basis 70 codieren, Folgendes ergibt:

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

Denken Sie daran, dass zwei benachbarte Ziffern (A B)durch ersetzt ((A-1) (B+70))werden können, und ändern Sie das Array von oben, sodass alle Ganzzahlen als druckbare ASCII-Zeichen codiert werden können:

["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
quelle
10

Python 2, 149 147 142 138 128 123 119 Bytes

Verwenden Sie einfach eine einfache Suche, um herauszufinden, welche Entfernungen verwendet werden müssen :) Dies definiert eine anonyme Funktion. Um sie zu verwenden, müssen Sie ihr einen Namen geben.

Vielen Dank an Sp3000 für Ideen, die eine Menge Bytes gespart haben!

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

Richtig eingerückt und zur besseren Lesbarkeit leicht ungolfed:

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

Rufen Sie wie folgt an:

f("Mercury","Mars")    -> 170030000
f("Neptune","Jupiter") -> -3722670000L
Kade
quelle
Ihrer Ausgabe fehlt eine 0, aber Sie scheinen mit dem richtigen Betrag zu multiplizieren.
Tim
@ Tim Ich habe in dem Beispielaufruf ein Durcheinander begangen, es hat eine vierte 0 am Ende: P
Kade
Du vergisst Pluto?
Will
@ Will Pluto muss nicht enthalten sein ...
Kade
(Sie werden mindestens zwei Bytes sparen, wenn Sie diesen zurückgegebenen -1-Trick aus meinem Eintrag kopieren, und dann werden Sie vor mir herziehen :)
Will
8

Prolog, 190 174 151 Bytes

Vielen Dank an Fatalize für die Anleitung.

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
quelle
Warum geben Sie dieses Ergebnis nicht direkt auf diese Weise zurück, s(A, B, R)anstatt zu schreiben R? Für Ausgaben ist nichts angegeben, daher sollte eine Prädikatenrückgabe in Ordnung sein.
Fatalize
Sie können auch 22 Bytes durch Modifizieren Prädikat abrasieren gzu 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]).und die Beseitigung aller Fakten für Planeten. Es ist weniger cool als, =..aber es ist kürzer, eine Schlüsselwertzuordnung zu erhalten
Fatalize
7

JavaScript (ES6), 115 bis 110 Byte

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

Dies ist eine anonyme Funktion, daher müssen Sie sie in einer Variablen speichern ( f=...; f("Earth", "Mercury")) oder als Ausdruck in Klammern verwenden () (...)("Earth", "Mercury").

Diese chaotischen Zeichenfolgen sind die ersten beiden Buchstaben jedes Planeten, gefolgt von der Entfernung dieses Planeten zum Merkur (geteilt durch 10000, um Platz zu sparen). Die innere Funktion gmacht folgendes:

  1. nimmt einen Namen ( k),
  2. reduziert es auf die ersten beiden Buchstaben ( k[0]+k[1]),
  3. verwendet eine Regex-Übereinstimmung, um die entsprechende Entfernung von Merkur zu finden, dividiert durch 10000 (z. B. sieht die Regex "Erde" so aus Ea(\d*)),
  4. multipliziert den Wert mit 10000 ( 1e4) und gibt das Ergebnis zurück.

Indem wir einen Quecksilberabstand vom anderen subtrahieren, erhalten wir den Abstand zwischen den Planeten.

Apsillers
quelle
@ vihan1086 Aha, ich habe den klassischen Fehler gemacht, Code-Punkt-Wert mit tatsächlicher
Bytedarstellung zu verwechseln
1
UTF-8 ist nur die falsche Kodierung für diesen Trick. Alle von zurückgegebenen Zeichen btoahaben Codepunkte unter 256, sodass ISO 8859-1 jedes Zeichen mit einem einzelnen Byte codiert.
Dennis
7

Java, 274 272 264 Bytes (einschließlich Pluto!)

  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);}

Input-Output:

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

Abstand und Tabbed:

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
quelle
1
Sie könnten viel abschneiden, indem Sie alle Zahlen durch 1000 teilen
Tim
Ich bin gerade dabei das zu tun!
DeadChex
1
Sie können auch die intund int[]int i=0,j=1,k[]={};
-Deklarationen
1
Sie können zwei Bytes abrasieren durch Ersetzen 10000mit 1e4.
Anubian Noob
1
da wir wissen, dass e > wSie ein Zeichen mit dem Operator "gehe zu" while(e-->w)for(;e--!=w;)
zuschneiden
6

Python, 118 Bytes

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 ist eine Funktion, die die Entfernung von Merkur zurückgibt.

Die Zeichenfolge enthält "VeEaMaJuSaUrNe"die ersten beiden Zeichen aller Planetennamen mit Ausnahme von Merkur . findkann Merkur nicht finden und gibt -1 zurück. -1/2 ist immer noch -1, also ist dies das letzte Element im Tupel, das 0 ist.

Einfacher Testcode:

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)
Wille
quelle
Schöner Trick da.
Anubian Noob
6

APL, 97 95 85 Bytes

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

Dies erzeugt eine unbenannte dyadische Funktion, die den Ursprungsplaneten als linkes Argument und den Zielplaneten als rechtes Argument verwendet.

Sie können es online ausprobieren !

Alex A.
quelle
4

J-- , 226 Bytes

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);}

Ich denke nicht, dass dies zählt, da ich die Sprache gemacht habe, während die Frage offen war, aber es war hauptsächlich ein Test, wie klein ich Java-Code komprimieren konnte. Dies ist völlig und vollständig basiert weg DeadChex Antwort .

So verwenden Sie es:

$ j-- planets.j-- Mercury Mars
170030000
Phase
quelle
4

Pyth - 59 53 Bytes

Codiert die Entfernung in Unicode-Codepunkten.

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

Die Namenssuche ist ein bisschen cool, weil sie sich herumschleift. Vielen Dank an @Dennis für die Empfehlung von Index 14 als kollisionsfreies Nachschlagen!

Probieren Sie es hier online .

Maltysen
quelle
Ich habe bei meiner ersten Überarbeitung Index 14 verwendet. Es ist kollisionsfrei.
Dennis
3

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
SteelRaven
quelle
3

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

Nicht abgeschlossen:

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
quelle
3

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}

Es ist als Skript konzipiert, das von der Kommandozeile aus ausgeführt werden soll ARGV. Rennen wie

$ 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.
quelle
3

Haskell, 160, 158, 157 Bytes

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

Anwendungsbeispiel:

*Main> Neptune # Jupiter
-3722670000

*Main> Mercury # Mars
170030000

So funktioniert es: Ich definiere einen neuen Datentyp, Pbei dem die Konstruktornamen die Namen der Planeten sind. Ich stelle es auch in die EnumKlasse, dh ich erhalte eine Zuordnung zu ganzen Zahlen über fromEnum(in der Reihenfolge der Definition beginnend mit Mercury->0 ). Diese Ganzzahl kann als Index für die Entfernungsliste verwendet werden.

Edit: @Kritzefitz hat zwei Bytes zum Speichern gefunden und @Alchymist ein weiteres. Vielen Dank!

nimi
quelle
Sie können die Klammern entfernen fromEnum xund zwei Bytes speichern.
Kritzefitz
Können Sie 10 ^ 4 anstelle von 10000 verwenden oder hat dies Auswirkungen auf die Ausgabe?
Alchymist
@Alchymist: Ja, das ist möglich. Vielen Dank!
Nimi
2

Julia, 206 203 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)

Dadurch wird eine unbenannte Funktion erstellt, die zwei Zeichenfolgen akzeptiert und eine Ganzzahl zurückgibt. Um es zu nennen, geben Sie ihm einen Namen.

Ungolfed + Erklärung:

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.
quelle
2

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){...}löst die Herausforderung. Für die Eingabe sind Namen von Planeten erforderlich, die exakt mit den Namen der Konstanten der Aufzählung übereinstimmen. Ich finde es toll, wie Java eine Methode zur Konvertierung von Zeichenfolgen in Aufzählungen für mich <3 bietet

Verwendung:

Z.d("Mercury","Pluto") kehrt zurück 5848470000

Z.d("Pluto","Mercury") kehrt zurück -5848470000

Z.d("Uranus","Neptune") kehrt zurück 1627450000

Z.d("Mars","Pluto") kehrt zurück 5678440000

Jack Ammo
quelle
1

C (gcc) Pre-Prozessor-Makro, 146 Bytes

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

Probieren Sie es online!

Gastropner
quelle