Рассчитайте релятивистскую скорость


10

В специальной теории относительности скорость движущегося объекта относительно другого объекта, который движется в противоположном направлении, определяется по формуле:

s=v+u1+vu/c2.

s = ( v + u ) / ( 1 + v * u / c ^ 2)

В этой формуле и - величины скоростей объектов, а - скорость света (которая приблизительно равна , достаточно близкое приближение для этого вызов).vuc3.0×108m/s

Например, если бы один объект двигался v = 50,000 m/s, а другой объект двигался u = 60,000 m/s, скорость каждого объекта относительно другого была бы приблизительно s = 110,000 m/s. Это то, что вы ожидаете при галилеевой относительности (где скорости просто складываются). Однако, если v = 50,000,000 m/sи u = 60,000,000 m/s, относительная скорость будет приблизительно 106,451,613 m/s, что значительно отличается от 110,000,000 m/sпредсказанного относительностью Галилея.

Соревнование

Учитывая два целых числа vи uтакое, что 0 <= v,u < c, вычислите релятивистскую аддитивную скорость, используя вышеупомянутую формулу, с c = 300000000. Вывод должен быть либо десятичным значением, либо сокращенной дробью. Выходные данные должны быть в пределах 0.001фактического значения для десятичного значения или точного значения для дроби.

Тестовые случаи

Формат: v, u -> exact fraction (float approximation)

50000, 60000 -> 3300000000000/30000001 (109999.99633333346)
50000000, 60000000 -> 3300000000/31 (106451612.90322581)
20, 30 -> 7500000000000000/150000000000001 (49.999999999999666)
0, 20051 -> 20051 (20051.0)
299999999, 299999999 -> 53999999820000000000000000/179999999400000001 (300000000.0)
20000, 2000000 -> 4545000000000/2250001 (2019999.1022226212)
2000000, 2000000 -> 90000000000/22501 (3999822.2301231055)
1, 500000 -> 90000180000000000/180000000001 (500000.9999972222)
1, 50000000 -> 90000001800000000/1800000001 (50000000.972222224)
200000000, 100000000 -> 2700000000/11 (245454545.45454547)

7
s/velocity/Velocity of an Unladen Swallow/g
mbomb007

1
"Галилеева относительность"? Возможно, это галилеевская механика, но я бы назвал вашу фразу оксюмороном (возможно, также анахроничным ретронимом). Хороший вопрос PPCG, хотя!
Тоби Спейт

Ответы:



11

Mathematica, 17 байт

+##/(1+##/9*^16)&

Безымянная функция, принимающая два целых числа и возвращающая точную дробь.

объяснение

Здесь используются два приятных трюка с последовательностью аргументов## , что позволяет мне избегать ссылки на отдельные аргументы uи vотдельно. ##расширяется до последовательности всех аргументов, которая является своего рода «развернутым списком». Вот простой пример:

{x, ##, y}&[u, v]

дает

{x, u, v, y}

То же самое работает внутри произвольных функций (поскольку {...}это просто сокращение для List[...]):

f[x, ##, y]&[u, v]

дает

f[x, u, v, y]

Теперь мы также можем передать ##операторам, которые сначала будут относиться к ним как к одному операнду. Тогда оператор будет расширен до полной формы f[...], и только тогда последовательность будет расширена. В этом случае +##, Plus[##]который есть Plus[u, v], то есть числитель мы хотим.

В знаменателе, с другой стороны, ##появляется как левый оператор /. Причина, по которой это умножается uи vявляется довольно тонкой. /реализуется с точки зрения Times:

FullForm[a/b]
(* Times[a, Power[b, -1]] *)

Поэтому , когда aесть ##, она будет расширена после этого и мы в конечном итоге

Times[u, v, Power[9*^16, -1]]

Здесь, *^просто оператор Mathematica для научной записи.


4

Желе, 9 байт

÷3ȷ8P‘÷@S

Попробуйте онлайн! С другой стороны , если вы предпочитаете фракции, вы можете выполнить один и тот же код с М .

Как это работает

÷3ȷ8P‘÷@S  Main link. Argument: [u, v]

÷3ȷ8       Divide u and v by 3e8.
    P      Take the product of the quotients, yielding uv ÷ 9e16.
     ‘     Increment, yielding 1 + uv ÷ 9e16.
        S  Sum; yield u + v.
      ÷@   Divide the result to the right by the result to the left.

3

Python3, 55 31 29 байт

Python ужасен для получения входных данных по мере необходимости, int(input()) но вот мое решение в любом случае:

V, U = INT (вход ()), Int (вход ()); печать ((V + U) / (1 + v * и / 9e16))

Благодаря @Jakube мне на самом деле не нужна вся программа, только функция. Следовательно:

lambda u,v:(v+u)/(1+v*u/9e16)

Скорее самоочевидный, получить входные данные, вычисления. Я использовал c ^ 2 и упростил это, поскольку 9e16 короче (3e8 ** 2).

Python2, 42 байта

v,u=input(),input();print(v+u)/(1+v*u/9e16)

Благодаря @muddyfish


1
Если вы используете python2, вы можете бросить int(input())и заменить его на input(), вы также можете снять скобки вокруг оператора печати
Blue

@Jakube Как бы вы получили входные данные, хотя? ОП говорит: «Даны два целых числа v и u»
Джордж

@Jakube Да, именно так я и использовал бы лямбду, но OP безоговорочно запрашивает всю программу, а не функцию. то есть он имеет вход и выход
джордж

@Jakube хорошо, в таком случае я немного проигрываю. Ура!
Георгий

Можно lambda u,v:(v+u)/(1+v*u/9e16), и это работает как для Python 2, так и для 3.
mbomb007


2

Matlab, 24 байта

@(u,v)(u+v)/(1+v*u/9e16)

Анонимная функция, которая принимает два входа. Ничего особенного, просто представлено для полноты.


Я предлагаю вам удалить «обычный» из названия. Если бы использовался набор инструментов, это должно быть упомянуто; так что вы можете смело просто сказать "Matlab". Ох и добро пожаловать в PPCG!
Луис Мендо

2

CJam, 16 байт

q~_:+\:*9.e16/)/

Я все еще уверен, что здесь можно сохранить байты


Вот два из этих байтов:q~d]_:+\:*9e16/)/
Мартин Эндер

@MartinEnder Спасибо, не знал о dтакой работе, но не могу поверить, что пропустил оператор приращения ...
Симмонс

Меньше 1 байта при вводе массива:q~_:+\:*9.e16/)/
Луис Мендо

2

Дьялог АПЛ , 11 байт

+÷1+9E16÷⍨×

Доля суммы и [прирост делится на девяносто квадриллионов и произведение]:

┌─┼───┐         
+ ÷ ┌─┼──────┐  
    1 + ┌────┼──┐
        9E16 ÷⍨ ×

÷⍨is «делит», как в «девяносто квадриллионов делит n », то есть эквивалентно n, деленному на девяносто квадриллионов.


Конечно, это 11 символов, а не байты, так как я уверен, что некоторые из этих символов не в ASCII?
Жюль

@Jules В UTF-8, конечно, но APL имеет свои собственные кодовые страницы, которые предшествуют Unicode на несколько десятилетий.
Деннис

2

Haskell, 24 байта

Как отдельная функция, которая может предоставлять либо число с плавающей запятой, либо дробное число, в зависимости от контекста, в котором она используется ...

r u v=(u+v)/(1+v*u/9e16)

Пример использования в REPL:

*Main> r 20 30
49.999999999999666
*Main> default (Rational)
*Main> r 20 30 
7500000000000000 % 150000000000001

Сохраните два байта, определив u#vвместо r u v.
Згарб





1

Нетер , 24 байта

Неконкурирующих

I~vI~u+1vu*10 8^3*2^/+/P

Попробуй это здесь!

Нётер кажется подходящим языком для решения этой проблемы, учитывая, что Эмми Нётер была пионером идей симметрии, которые привели к уравнениям Эйнштейна (это и E = mc^2т. Д.)

В любом случае, это в основном перевод данного уравнения в обратную польскую запись.



0

PowerShell, 34 байта

param($u,$v)($u+$v)/(1+$v*$u/9e16)

Чрезвычайно простая реализация. Нет надежды на то, чтобы догнать кого-либо, хотя, благодаря 6 $требуется.




0

ForceLang, 116 байт

Неконкурентоспособен, использует языковую функциональность, добавленную после публикации заявки.

def r io.readnum()
set s set
s u r
s v r
s w u+v
s c 3e8
s u u.mult v.mult c.pow -2
s u 1+u
io.write w.mult u.pow -1


0

постоянный ток, 21 байт

svddlv+rlv*9/I16^/1+/

Это предполагает, что точность уже установлена, например, с 20k . Добавьте 3 байта, если вы не можете сделать это предположение.

Более точная версия

svdlv+9I16^*dsc*rlv*lc+/

на 24 байта.

Оба они являются достаточно точными транскрипциями формулы, при этом единственным заметным видом игры в гольф является использование 9I16^*для c².


0

PHP, 44 45 байт

Анонимная функция, довольно простая.

function($v,$u){echo ($v+$u)/(1+$v*$u/9e16);}

3
Тебе нужен c^2знаменатель ... т.е. 9e16или эквивалентный.
AdmBorkBork

0

На самом деле, 12 байтов

;8╤3*ì*πu@Σ/

Попробуйте онлайн!

Объяснение:

;8╤3*ì*πu@Σ/
;             dupe input
 8╤3*ì*       multiply each element by 1/(3e8)
       πu     product, increment
         @Σ/  sum input, divide sum by product


0

Forth (gforth) , 39 байтов

: f 2dup + s>f * s>f 9e16 f/ 1e f+ f/ ;

Попробуйте онлайн!

Код Объяснение

: f            \ start a new work definition
  2dup +       \ get the sum of u and v
  s>f          \ move to top of floating point stack
  * s>f        \ get the product of u and v and move to top of floating point stack
  9e16 f/      \ divide product by 9e16 (c^2)
  1e f+        \ add 1
  f/           \ divide the sum of u and v by the result
;              \ end word definition
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.