2つの惑星の名前を与えられ、距離を与える


25

次の表(source)を使用して、2つの惑星の名前を取得し、それらの間の距離を返すコードをいくつか作成します。

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

例、入力してから出力:

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

木星が海王星の前に来るので、そこの否定的なサインに注意してください。これらもすべて整数です。

uto王星を含める必要はありません(主に距離を計算するのが難しい奇妙な軌道のためです-与えられた距離は私自身の計算ですが、Pl王星はすべて有名です...)。

惑星間の距離によって私は軌道を意味している-私は日付を期待していませんし、それらがどこにあるかを解決します。

これはコードゴルフで、最短のコードが勝ちます。


10
「coz uto王星は惑星ではない」ための+1
オプティマイザー

@Optimizer私は距離を必要とするプロジェクトを行っていますが、誰も同意できません!私はそれを軌道周期と軌道速度を使用することに頼り
ティム

関数/プログラムはフロートを返すことができますか?すなわちMercury, Mars -> 170030000.0
ケード

8
それは暗示されていますが、惑星がすべて直線であり、任意の2つの隣接していない惑星間の距離がその間の距離の合計である聖なる瞬間を仮定していますか?
Sp3000

3
bytes王星(バイト以外)を含めるとペナルティがありますか?私はそれがちょっと悪いと感じています、それはちょうどそれが
重要

回答:


24

CJam、54 51 44バイト

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

CJamインタープリターでオンラインで試してください。

アイディア

単純なハッシュ関数を使用して、8つの惑星すべてを識別します。次に8を法と、そのコードポイントの配列として、それぞれの名前を考慮整数にベース26からそれらを変換し、結果のモジュロ93をとることによって、水星金星地球など、にマップ2401356および7

ここで、海王星から320,000 km離れた地点を選択し、その地点までの8つの惑星すべての距離を計算します。4つの末尾のゼロを削除し、上から8つのインデックスに合うように惑星を並べ替えた後、配列を取得します

[435172 427338 444341 372299 439312 307672 162777 32]

基数70の各整数をエンコードすると、次のようになります。

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

隣接する2つの数字(A B)をに置き換えることができることを思い出して((A-1) (B+70))、上から配列を変更して、すべての整数を印刷可能なASCII文字としてエンコードできるようにします。

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

パイソン2、149 147 142 138 128 123 119バイト

単純なルックアップを使用して、使用する距離を特定します:)これは匿名関数を定義するため、使用するには名前を付ける必要があります。

大量のバイトを節約したアイデアを提供してくれたSp3000に感謝します!

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

読みやすくするために、適切にインデントし、わずかにアンゴルフしました。

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

次のように呼び出します。

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

出力には0がありませんが、適切な量を掛けているようです。
ティム

@Tim私は例の呼び出しで台無しに、それは最後に4番目の0を持っています:P
Kade

pl王星を忘れていますか?
ウィル

@ウィルPl王星を含める必要はありません
ケード

(:)あなたが私のエントリからその検索の復帰-1トリックをコピーする場合は、少なくとも2つのバイトを保存します、その後、あなたは先に私の引っ張るだろう
ウィル

8

プロローグ、190 174 151バイト

指導のためにFatalizeに感謝します。

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

s(A, B, R)書く代わりに、このようにこの結果を直接返してみませんRか?出力には何も指定されていないため、述語の戻り値は問題ありません。
-19:

惑星のすべてのファクトを削除して述語gを変更することにより、22バイトを削減することもできます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]).。それよりもクールではあり=..ませんが、キーと値のマッピングを取得するのに時間が
かかり

7

JavaScript(ES6)、115 110バイト

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

これは匿名関数であるため、変数に保存するf=...; f("Earth", "Mercury")か()、括弧で囲んだ式として使用する必要があります()(...)("Earth", "Mercury")

その乱雑な文字列は、各惑星の最初の2文字であり、その後にその惑星の水星からの距離が続きます(スペースを節約するために10000で割られます)。内部関数gは次のことを行います。

  1. 名前(k)を取ります。
  2. 最初の2文字(k[0]+k[1])に減らします。
  3. 正規表現一致を使用して、10000で割った水星からの対応する距離を検索します(たとえば、「Earth」正規表現はのようになりますEa(\d*))。
  4. 値に10000(1e4)を掛けて、結果を返します。

ある水星から他の水星までの距離を引くことにより、惑星間の距離を取得します。


@ vihan1086ああ、私はコードポイント値と実際のバイト表現を混同する古典的な失敗をしました:(
apsillers

1
UTF-8は、このトリックの間違ったエンコーディングです。によって返されるすべての文字のbtoaコードポイントは256未満であるため、ISO 8859-1は1バイトを使用して各文字をエンコードします。
デニス

7

Java、274 272 264バイト(Pl王星を含む!)

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

入出力:

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

スペースとタブ付き:

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
すべての数値を1000で除算することにより、多くを切り捨てることができます。
ティム

それをやろうとしている!
DeadChex

1
配列が最後に来る場合は、intとの両方のint[]宣言を1行に置くこともできます。いいねint i=0,j=1,k[]={};
-Geobits

1
に置き換えることで10000、2バイトを削ることができます1e4
アヌビアヌーブ

1
e > wwhile(e-->w)for(;e--!=w;)
Gos

6

Python、118バイト

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 は、水星からの距離を返す関数です。

文字列"VeEaMaJuSaUrNe"は、水星を除くすべての惑星名の最初の2文字です。 find水星が見つからないため、-1を返します。-1/2はまだ-1なので、これはタプルの最後の要素、つまり0です。

簡単なテストコード:

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)

ナイストリック。
アヌビアヌーブ

6

APL、97 95 85バイト

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

これにより、名前のないダイアディック関数が作成されます。この関数は、左の引数として起点の惑星を、右の引数として終点の惑星を取ります。

オンラインで試すことができます


4

J--、226バイト

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

質問が出されている間に言語を作成していたので、これは重要ではないと思いますが、それはほとんどJavaコードを圧縮できるかどうかのテストでした。これは完全完全DeadChexの回答に基づいています

使用方法は次のとおりです。

$ j-- planets.j--水星火星
170030000

4

Pyth- 59 53バイト

距離をUnicodeコードポイントでエンコードします。

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

名前のルックアップはループするため、ちょっとクールです。インデックス14を衝突のないルックアップとして提案してくれた@Dennisに感謝します!

こちらからオンラインでお試しください


最初のリビジョンではインデックス14を使用しました。衝突はありません。
デニス

3

バッシュ、140バイト

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バイト

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

未縮小:

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

ルビー、168バイト

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}

コマンドラインから実行されるスクリプトとして設計されているため、を使用しARGVます。として実行

$ 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バイト

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

使用例:

*Main> Neptune # Jupiter
-3722670000

*Main> Mercury # Mars
170030000

仕組み:Pコンストラクター名が惑星の名前である新しいデータ型を定義します。また、Enumクラスに配置します。つまり、fromEnum(定義の順序で、Mercury-> で始まる)を介して整数へのマッピングを取得します0。この整数は、距離リストのインデックスとして使用できます。

編集:@Kritzefitzは保存するために2バイトを見つけ、@ Alchymistはもう1バイトを見つけました。ありがとう!


括弧を削除して、fromEnum x2バイト節約できます。
クリッツフィッツ

10000の代わりに10 ^ 4を使用できますか、または出力に影響しますか?
アルキミスト

@Alchymist:はい、可能です。ありがとう!
nimi

2

ジュリア、206の 203 190バイト

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

これにより、2つの文字列を受け入れて整数を返す名前のない関数が作成されます。呼び出すには、名前を付けます。

Ungolfed +説明:

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バイト

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){...}課題を解決します。入力には、列挙型の定数の名前と正確に一致する惑星の名前が必要です。Javaが私に変換メソッドを列挙する文字列を提供する方法が大好き<3

使用法:

Z.d("Mercury","Pluto") 返す 5848470000

Z.d("Pluto","Mercury") 返す -5848470000

Z.d("Uranus","Neptune") 返す 1627450000

Z.d("Mars","Pluto") 返す 5678440000


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.