Dati i nomi di due pianeti, indica la distanza


25

Usando la seguente tabella ( sorgente ) scrivi del codice che prende i nomi di due pianeti e restituisce la distanza tra loro:

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

Esempi, input quindi output:

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

Nota il segno negativo lì, poiché Giove viene prima di Nettuno. Sono anche tutti numeri interi.

Plutone non deve essere incluso (principalmente a causa di una strana orbita che rende difficile calcolare la distanza - quella distanza è il mio calcolo, ma poiché Plutone è tutto famoso ora ...).

Per distanza tra i pianeti intendo le orbite - non mi aspetto una data e capire dove si trovano.

Questo è il codice golf, il codice più corto vince.


10
+1 per non "perché Plutone non è un pianeta"
Ottimizzatore,

@Optimizer Sto facendo un progetto che ha bisogno delle distanze e nessuno può essere d'accordo! Ho fatto ricorso al periodo orbitale e alla velocità orbitale ...
Tim

La nostra funzione / programma può restituire un float? cioè Mercury, Mars -> 170030000.0?
Kade,

8
È implicito, ma stiamo assumendo il momento santo nel tempo in cui i pianeti sono tutti in linea retta e la distanza tra due pianeti non adiacenti è la somma delle distanze in mezzo?
Sp3000,

3
C'è una penalità per l'inclusione di Plutone (oltre ai byte)? Mi sento un po 'male per questo, ha appena avuto il suo grande giorno e tutto ...
DeadChex

Risposte:


24

CJam, 54 51 44 byte

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

Provalo online nell'interprete CJam .

Idea

Usiamo una semplice funzione di hashing per identificare tutti e otto i pianeti. Considerando ogni nome come la matrice dei suoi punti di codice, convertendoli dalla base 26 in numero intero e prendendo il risultato modulo 93, quindi modulo 8, Mercurio , Venere , Terra , ecc. Mappa in 2 , 4 , 0 , 1 , 3 , 5 , 6 e 7 .

Ora, scegliamo un punto che si trova 320.000 km dietro Nettuno e calcoliamo le distanze di tutti gli otto pianeti fino a quel punto. Dopo aver lasciato cadere quattro zeri finali e riordinato i pianeti in modo che si adattino agli 8 indici dall'alto, otteniamo l'array

[435172 427338 444341 372299 439312 307672 162777 32]

che, se codifichiamo ogni intero nella base 70, produce quanto segue:

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

Ricordando che è (A B)possibile sostituire due cifre adiacenti ((A-1) (B+70)), possiamo modificare l'array dall'alto in modo che tutti i numeri interi possano essere codificati come caratteri ASCII stampabili:

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

Codice

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.

10

Python 2, 149 147 142 138 128 123 119 byte

Usa solo una semplice ricerca per capire quali distanze usare :) Questo definisce una funzione anonima, quindi per usarla dovrai dargli un nome.

Grazie a Sp3000 per idee che hanno salvato un sacco di byte!

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

Rientrato correttamente e leggermente non golfato per leggibilità:

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

Chiama così:

f("Mercury","Mars")    -> 170030000
f("Neptune","Jupiter") -> -3722670000L

Nel tuo output manca uno 0, ma sembra che tu stia moltiplicando per la giusta quantità.
Tim

@Tim Ho incasinato nella chiamata di esempio, ha un quarto 0 alla fine: P
Kade

Stai dimenticando Plutone?
Will

@Will Pluto non deve essere incluso ...
Kade

(Salverai almeno due byte se copi quella trovata che restituisce -1 trucco dalla mia voce, e poi ti tirerai davanti a me :)
Will

8

Prolog, 190 174 151 byte

Grazie a Fatalize per la guida.

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

Perché non restituisci questo risultato direttamente in questo modo s(A, B, R)invece di scrivere R? Non viene specificato nulla per gli output, quindi un ritorno predicato dovrebbe andare bene.
Fatalizza il

È inoltre possibile radere 22 byte modificando predicato ga 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]).e la rimozione di tutti i fatti per i pianeti. È meno bello di =..ma è più breve ottenere una mappatura dei valori-chiave
fatalizza il

7

JavaScript (ES6), 115 110 byte

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

Questa è una funzione anonima, quindi dovrai memorizzarla in una variabile (f=...; f("Earth", "Mercury") ) o usarla come espressione tra parentesi ( (...)("Earth", "Mercury").

Quella stringa disordinata sono le prime due lettere di ogni pianeta, seguite dalla distanza di quel pianeta da Mercurio (divisa per 10000, per risparmiare spazio). La funzione interioreg esegue le seguenti operazioni:

  1. prende un nome (k ),
  2. lo riduce alle prime due lettere ( k[0]+k[1]),
  3. usa una corrispondenza regex per trovare la distanza corrispondente da Mercurio, divisa per 10000 (ad esempio, il regex "Terra" sembra Ea(\d*) ),
  4. moltiplica il valore per 10000 (1e4 ) e restituisce il risultato.

Sottraendo una distanza di mercurio dall'altra, otteniamo la distanza tra i pianeti.


@ vihan1086 Aha, ho commesso il classico errore di confondere codice-punto-valore con rappresentazione byte reale :(
apsillers

1
UTF-8 è solo la codifica sbagliata per questo trucco. Tutti i caratteri restituiti da btoahanno punti di codice inferiori a 256, quindi ISO 8859-1 codificherà ogni carattere utilizzando un singolo byte.
Dennis,

7

Java, 274 272 264 byte (include Plutone!)

  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

Distanziati e a schede:

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

1
Puoi tagliare molto dividendo tutti i numeri per 1000
Tim

Sto per farlo!
DeadChex,

1
Puoi anche mettere entrambe le dichiarazioni inte int[]su una riga se l'array arriva per ultimo: Likeint i=0,j=1,k[]={};
Geobits

1
È possibile radere due byte sostituendo 10000con 1e4.
Anubian Noob,

1
poiché sappiamo e > wche puoi tagliare un personaggio usando l'operatore va: while(e-->w)che è di 12 caratteri, invece di for(;e--!=w;)13.
corsiKa

6

Python, 118 byte

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 è una funzione che restituisce distanza da Mercurio.

La stringa "VeEaMaJuSaUrNe"è i primi due caratteri di tutti i nomi dei pianeti tranne Mercurio . findimpossibile trovare Mercurio quindi restituirà -1. -1/2 è ancora -1, quindi questo è l'ultimo elemento della tupla, che è 0.

Codice test semplice:

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)

Bel trucco lì.
Anubian Noob,

6

APL, 97 95 85 byte

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

Questo crea una funzione diadica senza nome che prende il pianeta di origine come argomento di sinistra e il pianeta di destinazione come di destra.

Puoi provarlo online !


4

J-- , 226 byte

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

Non penso che ciò valga quando stavo facendo la lingua mentre la domanda era fuori discussione, ma era principalmente una prova di quanto piccolo potevo comprimere il codice Java. Questo è totalmente e completamente basato sulla risposta di DeadChex .

Ecco come usarlo:

$ j-- planets.j-- Mercury Mars
170030000

4

Pyth - 59 53 byte

Codifica la distanza in punti di codice unicode.

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

La ricerca del nome è piuttosto interessante perché si avvolge intorno. Grazie a @Dennis per aver suggerito l'indice 14 come ricerca senza collisioni!

Provalo qui online .


Ho usato l'indice 14 nella mia prima revisione. È privo di collisioni.
Dennis,

3

Bash, 140 byte

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

3

CoffeeScript, 183 180 byte

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

3

Rubino, 168 byte

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}

È progettato come uno script da eseguire dalla riga di comando, quindi utilizza ARGV. Correre come

$ 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

3

Haskell, 160 158 157 byte

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

Esempio di utilizzo:

*Main> Neptune # Jupiter
-3722670000

*Main> Mercury # Mars
170030000

Come funziona: definisco un nuovo tipo di dati in Pcui i nomi dei costruttori sono i nomi dei pianeti. L'ho anche inserito nella Enumclasse, cioè ottengo un mapping su numeri interi tramite fromEnum(in ordine di definizione, iniziando con Mercury-> 0). Questo numero intero può essere utilizzato come indice per l'elenco delle distanze.

Modifica: @Kritzefitz ha trovato due byte da salvare e @Alchymist un altro. Grazie!


È possibile rimuovere le parentesi fromEnum xe salvare due byte.
Kritzefitz,

Puoi usare 10 ^ 4 invece di 10000 o influenzerà l'output?
Alchymist,

@Alchymist: sì, è possibile. Grazie!
nimi,

2

Julia, 206 203 190 byte

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

Ciò crea una funzione senza nome che accetta due stringhe e restituisce un numero intero. Per chiamarlo, dagli un nome.

Ungolfed + spiegazione:

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

2

Giava, 257 228 byte

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){...}risolve la sfida. L'input richiede che i nomi dei pianeti corrispondano esattamente ai nomi delle costanti dell'enum. Adoro come java fornisca una stringa per enumare il metodo di conversione per me <3

Uso:

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

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

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

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


1

Macro pre-processore C (gcc) , 146 byte

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

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.