Давши назви двох планет, дайте відстань


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?
Кейд

8
Це мається на увазі, але чи припускаємо ми святий момент часу, коли всі планети знаходяться по прямій лінії, а відстань між будь-якими двома сусідніми планетами - це сума відстаней між ними?
Sp3000

3
Чи існує штраф за включення Плутона (крім байтів)? Я відчуваю себе якось погано, просто у нього був великий день і все ...
DeadChex

Відповіді:


24

CJam, 54 51 44 байт

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

Спробуйте його в Інтернеті в інтерпретаторі CJam .

Ідея

Ми використовуємо просту функцію хешування для ідентифікації всіх восьми планет. Розглядаючи кожне ім'я як масив його кодових точок, перетворюючи їх з бази 26 в ціле число та приймаючи результат модуля 93, тоді модуль 8, Меркурій , Венера , Земля тощо відображають на 2 , 4 , 0 , 1 , 3 , 5 , 6 і 7 .

Тепер ми вибираємо точку, яка лежить на 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

Пітон 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 Я заплутався в прикладі виклику, у нього є четвертий 0 в кінці: P
Каде

Ви забуваєте плуто?
Буде

@Білл Плутон не повинен бути включений ...
Кейд

(Ви врятуєте по крайней мере , два байта , якщо ви копіюєте , що знахідку повернення -1 трюк з мого входу, а потім ви будете тягти попереду мене :)
Волю

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 байта, змінивши предикат gдля 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]).і видалення всіх фактів для планет. Це менш круто, ніж, =..але коротше, щоб отримати відображення ключових значень
Fatalize

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 (наприклад, вираз "Земля" виглядає Ea(\d*)),
  4. помножує значення на 10000 ( 1e4) і повертає результат.

Віднімаючи одну відстань Меркурія від іншої, ми отримуємо відстань між планетами.


@ vihan1086 Ага, я зробив класичну помилку заплутаного значення кодової точки з фактичним представленням байтів :(
apsillers

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
Тім

Просто збираюся це зробити!
DeadChex

1
Ви також можете поставити як intі int[]декларації в один рядок, якщо масив останній: Likeint i=0,j=1,k[]={};
Geobits

1
Ви можете поголити два байти, замінивши 10000на 1e4.
Anubian Noob

1
оскільки ми знаємо, що e > wви можете обрізати персонажа, використовуючи оператор while(e-->w)for(;e--!=w;)
go

6

Пітон, 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"- це перші два символи всіх імен планети, крім Меркурія . 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

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-- планети.j-- Маркус Меркурій
170030000

4

Pyth - 59 53 байти

Кодує відстань у кодових точках unicode.

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

Пошук назв начебто класний, тому що він обертається навколо. Дякуємо @Dennis за те, що він запропонував індекс 14 як пошук без зіткнення!

Спробуйте це онлайн .


Я використовував індекс 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 знайшов два байти для збереження, а @Alchymist ще один. Спасибі!


Ви можете видалити круглі дужки навколо fromEnum xі зберегти два байти.
Kritzefitz

Чи можете ви використовувати 10 ^ 4 замість 10000 або це вплине на вихід?
Алхімік

@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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.