11
\$\begingroup\$

In special relativity, the velocity of a moving object relative to another object that is moving in the opposite direction is given by the formula:

\begin{align}s = \frac{v+u}{1+vu/c^2}.\end{align}

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

In this formula, \$v\$ and \$u\$ are the magnitudes of the velocities of the objects, and \$c\$ is the speed of light (which is approximately \$3.0 \times 10^8 \,\mathrm m/\mathrm s\$, a close enough approximation for this challenge).

For example, if one object was moving at v = 50,000 m/s, and another object was moving at u = 60,000 m/s, the velocity of each object relative to the other would be approximately s = 110,000 m/s. This is what you would expect under Galilean relativity (where velocities simply add). However, if v = 50,000,000 m/s and u = 60,000,000 m/s, the relative velocity would be approximately 106,451,613 m/s, which is significantly different than the 110,000,000 m/s predicted by Galilean relativity.

The Challenge

Given two integers v and u such that 0 <= v,u < c, calculate the relativistic additive velocity, using the above formula, with c = 300000000. Output must be either a decimal value or a reduced fraction. The output must be within 0.001 of the actual value for a decimal value, or exact for a fraction.

Test Cases

Format: 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)
\$\endgroup\$
3
  • 7
    \$\begingroup\$ s/velocity/Velocity of an Unladen Swallow/g \$\endgroup\$
    – mbomb007
    Jun 14, 2016 at 16:19
  • 1
    \$\begingroup\$ "Gallilean relativity"? Gaillilean mechanics, perhaps, but I'd call your phrase an oxymoron (possibly an anachronistic retronym, too). Good PPCG question, though! \$\endgroup\$ Jun 15, 2016 at 9:37
  • 7
    \$\begingroup\$ @TobySpeight en.wikipedia.org/wiki/Galilean_invariance \$\endgroup\$
    – user45941
    Jun 15, 2016 at 9:38

27 Answers 27

12
\$\begingroup\$

Mathematica, 17 bytes

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

An unnamed function taking two integers and returning an exact fraction.

Explanation

This uses two nice tricks with the argument sequence ##, which allows me to avoid referencing the individual arguments u and v separately. ## expands to a sequence of all arguments, which is sort of an "unwrapped list". Here is a simple example:

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

gives

{x, u, v, y}

The same works inside arbitrary functions (since {...} is just shorthand for List[...]):

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

gives

f[x, u, v, y]

Now we can also hand ## to operators which will first treat them as a single operand as far as the operator is concerned. Then the operator will be expanded to its full form f[...], and only then is the sequence expanded. In this case +## is Plus[##] which is Plus[u, v], i.e. the numerator we want.

In the denominator on the other hand, ## appears as the left-hand operator of /. The reason this multiplies u and v is rather subtle. / is implemented in terms of Times:

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

So when a is ##, it gets expanded afterwards and we end up with

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

Here, *^ is just Mathematica's operator for scientific notation.

\$\endgroup\$
6
\$\begingroup\$

MATL, 9 bytes

sG3e8/pQ/

Try it online!

s      % Take array [u, v] implicitly. Compute its sum: u+v
G      % Push [u, v] again
3e8    % Push 3e8
/      % Divide. Gives [u/c, v/c]
p      % Product of array. Gives u*v/c^2
Q      % Add 1
/      % Divide. Display implicitly
\$\endgroup\$
4
\$\begingroup\$

Jelly, 9 bytes

÷3ȷ8P‘÷@S

Try it online! Alternatively, if you prefer fractions, you can execute the same code with M.

How it works

÷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.
\$\endgroup\$
3
\$\begingroup\$

Python3, 55 31 29 bytes

Python is awful for getting inputs as each input needs int(input()) but here is my solution anyway:

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

Thanks to @Jakube I don't actually need the whole prgrame, just the function. Hence:

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

Rather self explanatory, get inputs, computes. I've used c^2 and simplified that as 9e16 is shorter than (3e8**2).

Python2, 42 bytes

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

Thanks to @muddyfish

\$\endgroup\$
5
  • 1
    \$\begingroup\$ If you use python2, you can drop the int(input()) and replace it with input(), you can also drop the brackets round the print statement \$\endgroup\$
    – Blue
    Jun 14, 2016 at 10:27
  • \$\begingroup\$ @Jakube How would you get the inputs though? OP says "Given two integers v and u" \$\endgroup\$
    – george
    Jun 14, 2016 at 10:44
  • \$\begingroup\$ @Jakube Yes that would be how I would use lambda in it, but OP is asking implicitly for the whole program not just a function. i.e it has an input and an output \$\endgroup\$
    – george
    Jun 14, 2016 at 10:58
  • \$\begingroup\$ @Jakube well in that case I golf it down a bit. Cheers! \$\endgroup\$
    – george
    Jun 14, 2016 at 11:15
  • \$\begingroup\$ You can have lambda u,v:(v+u)/(1+v*u/9e16), and this works for both Python 2 and 3. \$\endgroup\$
    – mbomb007
    Jun 14, 2016 at 16:22
2
\$\begingroup\$

J, 13 11 bytes

+%1+9e16%~*

Usage

>> f =: +%1+9e16%~*
>> 5e7 f 6e7
<< 1.06452e8

Where >> is STDIN and << is STDOUT.

\$\endgroup\$
2
\$\begingroup\$

Matlab, 24 bytes

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

Anonymous function that takes two inputs. Nothing fancy, just submitted for completeness.

\$\endgroup\$
1
  • \$\begingroup\$ I suggest you remove "regular" from the title. If a toolbox were used it would have to be mentioned; so you can safely just say "Matlab". Oh and welcome to PPCG! \$\endgroup\$
    – Luis Mendo
    Jun 14, 2016 at 14:28
2
\$\begingroup\$

CJam, 16 Bytes

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

I'm still sure there are bytes to be saved here

\$\endgroup\$
3
  • \$\begingroup\$ Here's two of those bytes: q~d]_:+\:*9e16/)/ \$\endgroup\$ Jun 14, 2016 at 14:44
  • \$\begingroup\$ @MartinEnder Thanks, didn't know about d working like that but can't believe i missed the increment operator.... \$\endgroup\$
    – A Simmons
    Jun 14, 2016 at 14:58
  • \$\begingroup\$ 1 byte fewer with array input: q~_:+\:*9.e16/)/ \$\endgroup\$
    – Luis Mendo
    Jun 14, 2016 at 15:19
2
\$\begingroup\$

Dyalog APL, 11 bytes

+÷1+9E16÷⍨×

The fraction of the sum and [the increment of the divides of ninety quadrillion and the product]:

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

÷⍨ is "divides", as in "ninety quadrillion divides n" i.e equivalent to n divided by ninety quadrillion.

\$\endgroup\$
2
  • \$\begingroup\$ Surely that's 11 characters, not bytes, as I'm pretty sure some of those symbols aren't in ASCII? \$\endgroup\$
    – Jules
    Jun 14, 2016 at 19:39
  • \$\begingroup\$ @Jules In UTF-8, certainly, but APL has its own code pages, which predate Unicode by a few decades. \$\endgroup\$
    – Dennis
    Jun 14, 2016 at 20:37
2
\$\begingroup\$

Haskell, 24 bytes

As a single function that can provide either a floating point or fractional number, depending on the context in which it's used...

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

Example usage in REPL:

*Main> r 20 30
49.999999999999666
*Main> default (Rational)
*Main> r 20 30 
7500000000000000 % 150000000000001
\$\endgroup\$
1
  • \$\begingroup\$ Save two bytes by defining u#v instead of r u v. \$\endgroup\$
    – Zgarb
    Jun 15, 2016 at 10:31
2
\$\begingroup\$

Noether, 24 bytes

Non-competing

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

Try it here!

Noether seems to be an appropriate language for the challenge given that Emmy Noether pioneered the ideas of symmetry which lead to Einstein's equations (this, E = mc^2 etc.)

Anyway, this is basically a translation of the given equation to reverse polish notation.

\$\endgroup\$
1
\$\begingroup\$

Pyke, 12 bytes

sQB9T16^*/h/

Try it here!

\$\endgroup\$
0
1
\$\begingroup\$

Pyth, 14 bytes

csQhc*FQ*9^T16

Test suite.

Formula: sum(input) / (1 + (product(input) / 9e16))

Bonus: click here!

\$\endgroup\$
2
  • 5
    \$\begingroup\$ It's really unnecessary to include "FGITW" on every solution that is the first on a challenge. \$\endgroup\$
    – user45941
    Jun 14, 2016 at 8:50
  • \$\begingroup\$ Sorry, I have deleted it. \$\endgroup\$
    – Leaky Nun
    Jun 14, 2016 at 8:55
1
\$\begingroup\$

Javascript 24 bytes

Shaved off 4 bytes thanks to @LeakyNun

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

Pretty straightforward

\$\endgroup\$
2
  • \$\begingroup\$ Would v=>u=>(v+u)/(1+v*u/9e16) be ok? \$\endgroup\$
    – Leaky Nun
    Jun 14, 2016 at 9:08
  • \$\begingroup\$ @LeakyNun yes it would according to this meta post \$\endgroup\$ Jun 14, 2016 at 9:56
1
\$\begingroup\$

Julia, 22 bytes

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

Try it online!

\$\endgroup\$
1
\$\begingroup\$

TI-Basic, 21 bytes

Prompt U,V:(U+V)/(1+UV/9ᴇ16
\$\endgroup\$
2
  • \$\begingroup\$ Isn't the E worth 2 bytes? \$\endgroup\$
    – Leaky Nun
    Jun 14, 2016 at 22:09
  • 3
    \$\begingroup\$ Please check for yourself first... tibasicdev.wikidot.com/e-ten \$\endgroup\$
    – Timtech
    Jun 14, 2016 at 22:13
1
\$\begingroup\$

TI-BASIC, 12 bytes

:sum(Ans/(1+prod(Ans/3ᴇ8

Takes input as a list of {U,V} on Ans.

\$\endgroup\$
1
\$\begingroup\$

Microscript II, 28 bytes

1s16Es9*s>Fs>Fs<d*</+s<o<+</
\$\endgroup\$
0
\$\begingroup\$

PowerShell, 34 bytes

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

Extremely straightforward implementation. No hope of catching up with anyone, though, thanks to the 6 $ required.

\$\endgroup\$
0
\$\begingroup\$

Oracle SQL 11.2, 39 bytes

SELECT (:v+:u)/(1+:v*:u/9e16)FROM DUAL;
\$\endgroup\$
0
\$\begingroup\$

T-SQL, 38 bytes

DECLARE @U REAL=2000000, @ REAL=2000000;
PRINT FORMAT((@U+@)/(1+@*@U/9E16),'g')

Try it online!

Straightforward formula implementation.

\$\endgroup\$
0
\$\begingroup\$

dc, 21 bytes

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

This assumes that the precision has already been set, e.g. with 20k. Add 3 bytes if you can't make that assumption.

A more accurate version is

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

at 24 bytes.

Both of them are reasonably faithful transcriptions of the formula, with the only notable golfing being the use of 9I16^* for c².

\$\endgroup\$
0
\$\begingroup\$

PHP, 44 45 bytes

Anonymous function, pretty straightforward.

function($v,$u){echo ($v+$u)/(1+$v*$u/9e16);}
\$\endgroup\$
1
  • 3
    \$\begingroup\$ You need c^2 in the denominator ... i.e., 9e16 or equivalent. \$\endgroup\$ Jun 14, 2016 at 12:59
0
\$\begingroup\$

Actually, 12 bytes

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

Try it online!

Explanation:

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

Java (JDK), 24 bytes

u->v->(u+v)/(1+u*v/9e16)

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Forth (gforth), 39 bytes

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

Try it online!

Code Explanation

: 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
\$\endgroup\$
0
\$\begingroup\$

Math++, 26 bytes

?>u
?>v
(v+u)/(1+v*u/9e16)
\$\endgroup\$
0
\$\begingroup\$

ForceLang, 116 bytes

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
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.