Diberi nama dua planet, berikan jarak

25

Menggunakan tabel berikut ( sumber ) menulis beberapa kode yang mengambil nama dua planet dan mengembalikan jarak di antara mereka:

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

Contoh, input lalu output:

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

Perhatikan tanda negatif di sana, karena Jupiter datang sebelum Neptunus. Mereka semua juga bilangan bulat.

Pluto tidak harus dimasukkan (sebagian besar karena orbit aneh yang membuatnya sulit untuk menentukan jarak - jarak yang diberikan adalah perhitungan saya sendiri, tetapi karena Pluto semuanya terkenal sekarang ...).

Dengan jarak antar planet, aku bermaksud mengorbit - aku tidak mengharapkan kencan dan mencari tahu di mana mereka berada.

Ini golf kode, kode terpendek menang.

Tim
sumber
10
+1 untuk bukan "karena Pluto bukan planet"
Pengoptimal
@Optimizer Saya sedang melakukan proyek yang membutuhkan jarak dan tidak ada yang bisa setuju! Saya menggunakan periode orbital dan kecepatan orbitalnya ...
Tim
Bisakah fungsi / program kami mengembalikan float? yaitu Mercury, Mars -> 170030000.0?
Kade
8
Ini tersirat, tetapi apakah kita mengasumsikan momen suci di waktu di mana planet-planet semua berada dalam garis lurus dan jarak antara dua planet yang tidak berbatasan adalah jumlah jarak di antara keduanya?
Sp3000
3
Apakah ada penalti untuk memasukkan Pluto (selain byte)? Saya merasa agak buruk untuk itu, baru saja mengalami hari besar dan semuanya ...
DeadChex

Jawaban:

24

CJam, 54 51 44 byte

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

Cobalah online di juru bahasa CJam .

Ide

Kami menggunakan fungsi hashing sederhana untuk mengidentifikasi delapan planet. Dengan mempertimbangkan setiap nama sebagai larik titik kode, mengubahnya dari basis 26 ke bilangan bulat dan mengambil modulo 93 hasil kemudian modulo 8, Merkurius , Venus , Bumi , dll. Peta ke 2 , 4 , 0 , 1 , 3 , 5 , 6 dan 7 .

Sekarang, kami memilih titik yang terletak 320.000 km di belakang Neptunus dan menghitung jarak semua delapan planet ke titik itu. Setelah menjatuhkan empat trailing nol dan menata ulang planet-planet sehingga sesuai dengan 8 indeks dari atas, kami mendapatkan array

[435172 427338 444341 372299 439312 307672 162777 32]

yang, jika kita menyandikan setiap bilangan bulat di basis 70, menghasilkan yang berikut:

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

Mengingat dua digit yang berdekatan (A B)dapat diganti dengan ((A-1) (B+70)), kita dapat memodifikasi array dari atas sehingga semua bilangan bulat dapat dikodekan sebagai karakter ASCII yang dapat dicetak:

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

Kode

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
sumber
10

Python 2, 149 147 142 138 128 123 119 Bytes

Cukup gunakan pencarian sederhana untuk mencari tahu jarak mana yang harus digunakan :) Ini mendefinisikan fungsi anonim, jadi untuk menggunakannya Anda harus memberinya nama.

Terima kasih kepada Sp3000 untuk ide-ide yang menyelamatkan banyak byte!

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

Diindentakan dengan benar dan sedikit tidak dibiakkan untuk dibaca:

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

Sebut seperti ini:

f("Mercury","Mars")    -> 170030000
f("Neptune","Jupiter") -> -3722670000L
Kade
sumber
Output Anda tidak memiliki 0, tetapi Anda tampaknya mengalikan dengan jumlah yang tepat.
Tim
@Tim Saya mengacaukan dalam contoh panggilan, itu memang memiliki 0 keempat di akhir: P
Kade
Anda lupa pluto?
Will
@Apakah Pluto tidak harus dimasukkan ...
Kade
(Anda akan menghemat setidaknya dua byte jika Anda menyalin yang menemukan -1 trik dari entri saya, dan kemudian Anda akan maju di depan saya :)
Will
8

Prolog, 190 174 151 byte

Terima kasih untuk Fatalize untuk bimbingan.

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
sumber
Mengapa Anda tidak mengembalikan hasil ini langsung seperti ini s(A, B, R)daripada menulis R? Tidak ada yang ditentukan untuk output sehingga pengembalian predikat harus baik-baik saja.
Fatalkan
Anda juga dapat mencukur 22 byte dengan memodifikasi predikat guntuk 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]).dan menghapus semua fakta planet. Ini kurang keren dari =..tetapi lebih pendek untuk mendapatkan pemetaan nilai kunci
Fatalize
7

JavaScript (ES6), 115 110 byte

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

Ini adalah fungsi anonim, jadi Anda harus menyimpannya dalam variabel ( f=...; f("Earth", "Mercury")) atau menggunakannya sebagai ekspresi kurung ( (...)("Earth", "Mercury").

Tali yang berantakan itu adalah dua huruf pertama dari setiap planet, diikuti oleh jarak planet itu dari Merkurius (dibagi 10.000, untuk menghemat ruang). Fungsi batin gmelakukan hal berikut:

  1. mengambil nama ( k),
  2. menguranginya menjadi dua huruf pertama ( k[0]+k[1]),
  3. menggunakan pencocokan regex untuk menemukan jarak yang sesuai dari Merkurius, dibagi dengan 10.000 (mis., sepertinya "Bumi" seperti regex Ea(\d*)),
  4. mengalikan nilainya dengan 10000 ( 1e4) dan mengembalikan hasilnya.

Dengan mengurangi satu jarak Merkurius dari yang lain, kita mendapatkan jarak antar planet.

apsillers
sumber
@ vihan1086 Aha, saya telah membuat kesalahan klasik membingungkan nilai-kode-titik dengan representasi byte aktual :(
apsillers
1
UTF-8 hanyalah penyandian yang salah untuk trik ini. Semua karakter yang dikembalikan oleh btoamemiliki poin kode di bawah 256, sehingga ISO 8859-1 akan mengkodekan setiap karakter menggunakan byte tunggal.
Dennis
7

Java, 274 272 264 byte (termasuk 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

Spasi dan tab:

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
sumber
1
Anda dapat memotong banyak dengan membagi semua angka dengan 1000
Tim
Akan melakukan itu!
DeadChex
1
Anda juga dapat meletakkan kedua deklarasi intdan int[]pada satu baris jika array datang terakhir: Sepertiint i=0,j=1,k[]={};
Geobits
1
Anda dapat memotong dua byte dengan menggantinya 10000dengan 1e4.
Anubian Noob
1
karena kami tahu e > wAnda dapat memangkas satu karakter menggunakan operator to go: while(e-->w)yang terdiri dari 12 karakter, dan bukan 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 adalah fungsi yang mengembalikan jarak dari Merkurius.

String "VeEaMaJuSaUrNe"adalah dua karakter pertama dari semua nama planet kecuali Merkurius . findtidak dapat menemukan Merkuri sehingga akan mengembalikan -1. -1/2 masih -1 jadi ini adalah elemen terakhir dalam tuple, yaitu 0.

Kode uji sederhana:

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)
Akan
sumber
Trik yang bagus di sana.
Anubian Noob
6

APL, 97 95 85 byte

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

Ini menciptakan fungsi diad tanpa nama yang menjadikan planet asal sebagai argumen kiri dan planet tujuan sebagai kanan.

Anda dapat mencobanya secara online !

Alex A.
sumber
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; gema (h * m);}

Saya tidak berpikir ini penting karena saya membuat bahasa sementara pertanyaan itu keluar, tapi itu sebagian besar merupakan tes seberapa kecil saya bisa memampatkan kode Java. Ini sepenuhnya dan sepenuhnya didasarkan pada jawaban DeadChex .

Berikut cara menggunakannya:

$ j-- planetets.j-- Merkurius Mars
170030000
tahap
sumber
4

Pyth - 59 53 byte

Mengkode jarak dalam unicode codepoints.

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

Pencarian nama agak keren karena loop sekitar. Terima kasih kepada @Dennis karena menyarankan indeks 14 sebagai pencarian bebas benturan!

Coba di sini online .

Maltysen
sumber
Saya menggunakan indeks 14 di revisi pertama saya. Itu bebas tabrakan.
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
SteelRaven
sumber
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

Tidak dijinakkan:

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

Ruby, 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}

Ini dirancang sebagai skrip untuk dijalankan dari baris perintah, jadi gunakan ARGV. Jalankan sebagai

$ 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.
sumber
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

Contoh penggunaan:

*Main> Neptune # Jupiter
-3722670000

*Main> Mercury # Mars
170030000

Cara kerjanya: Saya mendefinisikan tipe data baru di Pmana nama konstruktor adalah nama-nama planet. Saya juga meletakkannya di Enumkelas, yaitu saya mendapatkan pemetaan ke bilangan bulat melalui fromEnum(dalam urutan definisi, dimulai denganMercury ->0 ). Bilangan bulat ini dapat digunakan sebagai indeks untuk daftar jarak.

Sunting: @Kritzefitz menemukan dua byte untuk disimpan dan @Alchymist satu lagi. Terima kasih!

nimi
sumber
Anda dapat menghapus tanda kurung di sekitar fromEnum xdan menyimpan dua byte.
Kritzefitz
Bisakah Anda menggunakan 10 ^ 4 bukan 10.000 atau akankah itu mempengaruhi output?
Alchymist
@Alymymist: ya, itu mungkin. Terima kasih!
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)

Ini menciptakan fungsi tanpa nama yang menerima dua string dan mengembalikan integer. Untuk menyebutnya, berikan nama.

Penjelasan + tidak dikumpulkan:

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

Jawa, 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){...}memecahkan tantangan. Input membutuhkan nama planet untuk mencocokkan nama konstanta enum dengan tepat. Saya suka bagaimana java menyediakan metode konversi string ke enum untuk saya <3

Pemakaian:

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

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

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

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

Jack Ammo
sumber
1

C (gcc) makro pra-prosesor, 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

Cobalah online!

gastropner
sumber