Cho tên của hai hành tinh, cho khoảng cách


25

Sử dụng bảng sau ( nguồn ) viết một số mã lấy tên của hai hành tinh và trả về khoảng cách giữa chúng:

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

Ví dụ, đầu vào rồi đầu ra:

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

Lưu ý dấu hiệu tiêu cực ở đó, vì Sao Mộc đến trước Sao Hải Vương. Họ cũng là tất cả các số nguyên.

Sao Diêm Vương không cần phải được đưa vào (chủ yếu là do quỹ đạo kỳ lạ khiến cho việc tìm ra khoảng cách trở nên khó khăn - khoảng cách đưa ra là tính toán của riêng tôi, nhưng hiện tại Pluto đã nổi tiếng ...).

Theo khoảng cách giữa các hành tinh, tôi có nghĩa là quỹ đạo - Tôi không mong đợi một ngày và tìm ra nơi chúng ở.

Đây là mã golf, mã ngắn nhất thắng.


10
+1 không phải là "vì sao Diêm Vương không phải là một hành tinh"
Trình tối ưu hóa

@Optimizer Tôi đang làm một dự án cần khoảng cách và không ai có thể đồng ý! Tôi đã sử dụng thời kỳ quỹ đạo và tốc độ quỹ đạo của nó ...
Tim

Chức năng / chương trình của chúng tôi có thể trả lại một float? tức là Mercury, Mars -> 170030000.0?
Kade

8
Điều đó ngụ ý, nhưng chúng ta có đang giả sử thời điểm thiêng liêng trong thời gian mà các hành tinh nằm trên một đường thẳng và khoảng cách giữa hai hành tinh không liền kề là tổng khoảng cách ở giữa không?
Sp3000

3
Có hình phạt nào bao gồm Sao Diêm Vương (ngoài các byte) không? Tôi cảm thấy hơi tệ cho nó, nó vừa có một ngày trọng đại ...
DeadChex

Câu trả lời:


24

CJam, 54 51 44 byte

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

Hãy thử trực tuyến trong trình thông dịch CJam .

Ý kiến

Chúng tôi sử dụng chức năng băm đơn giản để xác định tất cả tám hành tinh. Bằng cách coi mỗi tên là mảng các điểm mã của nó, chuyển đổi chúng từ cơ sở 26 sang số nguyên và lấy kết quả modulo 93 sau đó modulo 8, Mercury , Venus , Earth , v.v. ánh xạ sang 2 , 4 , 0 , 1 , 3 , 5 , 67 .

Bây giờ, chúng tôi chọn một điểm nằm sau Sao Hải Vương 320.000 km và tính khoảng cách của tất cả tám hành tinh đến điểm đó. Sau khi thả bốn số 0 ở cuối và sắp xếp lại các hành tinh sao cho phù hợp với 8 chỉ số từ trên xuống, chúng ta có được mảng

[435172 427338 444341 372299 439312 307672 162777 32]

trong đó, nếu chúng ta mã hóa từng số nguyên trong cơ sở 70, sẽ mang lại kết quả như sau:

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

Hãy nhớ rằng hai chữ số liền kề (A B)có thể được thay thế bằng ((A-1) (B+70)), chúng ta có thể sửa đổi mảng từ trên xuống để tất cả các số nguyên có thể được mã hóa thành các ký tự ASCII có thể in được:

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

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

Chỉ cần sử dụng một tra cứu đơn giản để tìm ra khoảng cách sử dụng :) Điều này xác định một chức năng ẩn danh, vì vậy để sử dụng nó, bạn sẽ cần đặt tên cho nó.

Cảm ơn Sp3000 vì những ý tưởng đã lưu một loạt byte!

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

Được thụt lề đúng cách và không được chỉnh sửa một chút để dễ đọc:

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

Gọi như vậy:

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

Đầu ra của bạn thiếu 0, nhưng dường như bạn được nhân với số lượng phù hợp.
Tim

@Tim Tôi đã nhầm trong cuộc gọi ví dụ, nó có số 0 thứ tư ở cuối: P
Kade

Bạn đang quên sao Diêm Vương?
Sẽ

@ Sẽ không bao gồm Sao Diêm Vương ...
Kade

(Bạn sẽ tiết kiệm được ít nhất hai byte nếu bạn sao chép mà tìm trở về -1 lừa từ entry của tôi, và sau đó bạn sẽ kéo phía trước của tôi :)
Will

8

Prolog, 190 174 151 byte

Cảm ơn Fatalize đã hướng dẫn.

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

Tại sao bạn không trả lại kết quả này trực tiếp như thế này s(A, B, R)thay vì viết R? Không có gì được chỉ định cho các kết quả đầu ra nên lợi nhuận của vị từ sẽ ổn.
Gây tử vong vào

Bạn cũng có thể tắt 22 byte bằng cách sửa đổi vị ngữ gthành 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]).và loại bỏ tất cả các sự kiện cho các hành tinh. Nó ít thú vị hơn =..nhưng lại ngắn hơn để có được ánh xạ giá trị khóa
Fatalize

7

JavaScript (ES6), 115 110 byte

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

Đây là một hàm ẩn danh, vì vậy bạn sẽ cần lưu trữ nó trong một biến ( f=...; f("Earth", "Mercury")) hoặc sử dụng nó như một biểu thức được ngoặc đơn ( (...)("Earth", "Mercury").

Chuỗi lộn xộn đó là hai chữ cái đầu tiên của mỗi hành tinh, theo sau là khoảng cách của hành tinh đó với Sao Thủy (chia cho 10000, để tiết kiệm không gian). Hàm bên trong gthực hiện như sau:

  1. lấy tên ( k),
  2. giảm nó xuống hai chữ cái đầu tiên ( k[0]+k[1]),
  3. sử dụng kết hợp regex để tìm khoảng cách tương ứng từ Sao Thủy, chia cho 10000 (ví dụ: regex "Trái đất" trông như thế nào Ea(\d*)),
  4. nhân giá trị với 10000 ( 1e4) và trả về kết quả.

Bằng cách trừ đi một khoảng cách Sao Thủy so với khoảng cách khác, chúng ta có được khoảng cách giữa các hành tinh.


@ vihan1086 Aha, tôi đã phạm phải sai lầm kinh điển về việc nhầm lẫn mã-điểm-giá trị với biểu diễn byte thực tế :(
apsillers

1
UTF-8 chỉ là mã hóa sai cho thủ thuật này. Tất cả các ký tự được trả về btoacó điểm mã dưới 256, do đó ISO 8859-1 sẽ mã hóa từng ký tự bằng một byte đơn.
Dennis

7

Java, 274 272 264 byte (bao gồm cả Sao Diêm Vương!)

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

Đầu ra đầu vào:

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

Khoảng cách và theo thẻ:

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
Bạn có thể cắt giảm rất nhiều bằng cách chia tất cả các số cho 1000
Tim

Chỉ cần làm điều đó!
DeadChex

1
Bạn cũng có thể đặt cả khai báo intint[]khai báo trên một dòng nếu mảng xuất hiện sau: Thíchint i=0,j=1,k[]={};
Geobits

1
Bạn có thể cạo sạch hai byte bằng cách thay thế 10000bằng 1e4.
Anubian Noob 16/07/2015

1
vì chúng tôi biết e > wbạn có thể cắt một ký tự bằng cách sử dụng toán tử đi tới: while(e-->w)đó là 12 ký tự, thay vì for(;e--!=w;)đó là 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 là một hàm trả về khoảng cách từ Sao Thủy.

Chuỗi "VeEaMaJuSaUrNe"là hai ký tự đầu tiên của tất cả các tên hành tinh ngoại trừ Sao Thủy . findkhông thể tìm thấy Sao Thủy nên sẽ quay lại -1. -1/2 vẫn là -1 nên đây là phần tử cuối cùng trong bộ dữ liệu, là 0.

Mã kiểm tra đơn giản:

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)

Thủ thuật hay đấy.
Anubian Noob

6

APL, 97 95 85 byte

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

Điều này tạo ra một hàm dyadic không tên, lấy hành tinh gốc làm đối số bên trái và hành tinh đích làm bên phải.

Bạn có thể thử trực tuyến !


4

J-- , 226 byte

chính {str q = "MeVeEaMaJuSaUrNePl"; int w = q.indexOf (a [0] .sub (0,2)) / 2, e = q.indexOf (a [1] .sub (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);}

Tôi không nghĩ rằng điều này được tính khi tôi tạo ra ngôn ngữ trong khi câu hỏi được đưa ra, nhưng nó chủ yếu là một thử nghiệm về việc tôi có thể nén mã Java nhỏ như thế nào. Điều này hoàn toànhoàn toàn dựa trên câu trả lời của DeadChex .

Đây là cách sử dụng nó:

$ j-- planets.j-- Sao Thủy
170030000

4

Pyth - 59 53 byte

Mã hóa khoảng cách trong các điểm mã unicode.

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

Tên tra cứu là hơi mát vì nó vòng quanh. Cảm ơn @Dennis đã gợi ý chỉ số 14 dưới dạng tra cứu miễn phí va chạm!

Hãy thử nó ở đây trực tuyến .


Tôi đã sử dụng chỉ số 14 trong lần sửa đổi đầu tiên. Nó là không va chạm.
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

Chưa hoàn thành:

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

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}

Nó được thiết kế như một tập lệnh được chạy từ dòng lệnh, do đó sử dụng ARGV. Chạy như

$ 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

Ví dụ sử dụng:

*Main> Neptune # Jupiter
-3722670000

*Main> Mercury # Mars
170030000

Cách thức hoạt động: Tôi xác định một kiểu dữ liệu mới Ptrong đó tên của hàm tạo là tên của các hành tinh. Tôi cũng đặt nó trong Enumlớp, tức là tôi có được ánh xạ tới các số nguyên thông qua fromEnum(theo thứ tự định nghĩa, bắt đầu bằng Mercury-> 0). Số nguyên này có thể được sử dụng như một chỉ mục cho danh sách khoảng cách.

Chỉnh sửa: @Kritzefitz tìm thấy hai byte để lưu và @Alchymist một byte khác. Cảm ơn!


Bạn có thể loại bỏ dấu ngoặc đơn xung quanh fromEnum xvà lưu hai byte.
Kritzefitz

Bạn có thể sử dụng 10 ^ 4 thay vì 10000 hoặc điều đó sẽ ảnh hưởng đến đầu ra không?
Alchymist

@ Alchymist: vâng, nó có thể. Cảm ơn!
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)

Điều này tạo ra một hàm không tên chấp nhận hai chuỗi và trả về một số nguyên. Để gọi nó, đặt tên cho nó.

Ungolfed + giải thích:

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

Java, 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){...}giải quyết các thách thức. Đầu vào yêu cầu tên của các hành tinh khớp chính xác với tên của hằng số enum. Tôi thích cách java cung cấp phương thức chuyển đổi chuỗi thành enum cho tôi <3

Sử dụng:

Z.d("Mercury","Pluto") trả lại 5848470000

Z.d("Pluto","Mercury") trả lại -5848470000

Z.d("Uranus","Neptune") trả lại 1627450000

Z.d("Mars","Pluto") trả lại 5678440000


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.