给定两个行星的名称,给定距离


25

使用下表(源代码)编写一些代码,该代码采用两个行星的名称并返回它们之间的距离:

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

注意那里的负号,因为木星先于海王星。它们也是整数。

不必把冥王星包括在内(主要是因为轨道怪异,很难计算出距离-给出的距离是我自己计算的,但由于冥王星现在已广为人知...)。

通过行星之间的距离,我的意思是轨道-我不希望有一个日期并确定它们的位置。

这是代码高尔夫球,最短的代码获胜。


10
+1(不是“因为冥王星不是行星”)
优化器

@Optimizer我正在做一个需要距离的项目,没有人可以同意!我求助于它的轨道周期和轨道速度...
蒂姆

我们的函数/程序可以返回浮点数吗?即Mercury, Mars -> 170030000.0
卡德2015年

8
这是隐含的,但我们是否假设行星都是直线的神圣时刻,并且任何两个不相邻的行星之间的距离是它们之间的距离之和?
Sp3000

3
包含冥王星(除字节外)有罚金吗?我觉得这很糟糕,因为今天过得很重要……
DeadChex 2015年

Answers:


24

CJam,54 51 44字节

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

CJam解释器中在线尝试。

理念

我们使用一个简单的哈希函数来识别所有八个行星。通过考虑每个名称作为其代码点的阵列,从基部26将它们转换为整数,并采取结果模93然后模8,金星地球等映射到24013567

现在,我们选择一个位于海王星后320,000公里处的点,并计算所有八个行星到该点的距离。删除四个尾随零并重新排列行星以使其适合上方的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]
]

请记住,(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

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

@Tim我弄混了示例调用,它的末尾确实有第四个0:P
Kade

你忘记冥王星了吗?
2015年

@Will Pluto不必包括在内……
Kade

(如果您复制从我的条目中返回-1技巧的副本,则将至少保存两个字节,然后您将领先于我:)
2015年

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?没有为输出指定任何内容,因此谓词返回应该很好。
致命

您也可以通过修改谓词剃掉22个字节gg(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")

凌乱的字符串是每个行星的前两个字母,然后是该行星与水星的距离(除以10000,以节省空间)。内部函数g执行以下操作:

  1. 名称(k),
  2. 将其减少为前两个字母(k[0]+k[1]),
  3. 使用正则表达式匹配项找到与水星的对应距离,除以10000(例如,“ Earth”正则表达式看起来像Ea(\d*)),
  4. 将值乘以10000(1e4)并返回结果。

通过从另一个减去一个水星距离,我们得到了行星之间的距离。


@ vihan1086啊哈,我犯了一个经典的错误,就是将代码点值与实际的字节表示相混淆:(
apsillers 2015年

1
UTF-8只是此技巧的错误编码。返回的所有字符的btoa代码点均低于256,因此ISO 8859-1将使用单个字节对每个字符进行编码。
丹尼斯

7

Java中,274个 272 264字节(包括冥王星!)

  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来减少很多费用
蒂姆(Tim)

就是要这样做!
DeadChex

1
如果数组排在最后,也可以将intint[]声明都放在一行上:Likeint i=0,j=1,k[]={};
Geobits

1
您可以通过更换剃掉两个字节100001e4
Anubian Noob 2015年

1
因为我们知道e > w,你可以使用去操作修剪字符:while(e-->w)这是12个字符,而不是for(;e--!=w;)它是13
corsiKa

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"除Mercury之外所有行星名称的前两个字符。 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)

那里不错的把戏。
Anubian Noob 2015年

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

名称查找有点酷,因为它会四处循环。感谢@Dennis建议索引14为无冲突查找!

在这里在线尝试


我在第一个修订版中使用了索引14。它是无碰撞的。
丹尼斯

3

Bash,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,183180字节

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

Ruby,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找到了两个要保存的字节,@ Alchymist找到了另一个。谢谢!


您可以删除括号fromEnum x并保存两个字节。
克里策夫兹

您可以使用10 ^ 4而不是10000还是会影响输出?
Alchymist

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

这将创建一个未命名的函数,该函数接受两个字符串并返回一个整数。要给它起个名字。

取消+说明:

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


1

C(gcc)预处理器宏,146个字节

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

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.