10
\$\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\$
  • 7
    \$\begingroup\$ s/velocity/Velocity of an Unladen Swallow/g \$\endgroup\$ – mbomb007 Jun 14 '16 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\$ – Toby Speight Jun 15 '16 at 9:37
  • 6
    \$\begingroup\$ @TobySpeight en.wikipedia.org/wiki/Galilean_invariance \$\endgroup\$ – Mego Jun 15 '16 at 9:38

25 Answers 25

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\$
11
\$\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\$
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\$
  • 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 '16 at 10:27
  • \$\begingroup\$ @Jakube How would you get the inputs though? OP says "Given two integers v and u" \$\endgroup\$ – george Jun 14 '16 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 '16 at 10:58
  • \$\begingroup\$ @Jakube well in that case I golf it down a bit. Cheers! \$\endgroup\$ – george Jun 14 '16 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 '16 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\$
  • \$\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 '16 at 14:28
2
\$\begingroup\$

CJam, 16 Bytes

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

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

\$\endgroup\$
  • \$\begingroup\$ Here's two of those bytes: q~d]_:+\:*9e16/)/ \$\endgroup\$ – Martin Ender Jun 14 '16 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 '16 at 14:58
  • \$\begingroup\$ 1 byte fewer with array input: q~_:+\:*9.e16/)/ \$\endgroup\$ – Luis Mendo Jun 14 '16 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\$
  • \$\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 '16 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 '16 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\$
  • \$\begingroup\$ Save two bytes by defining u#v instead of r u v. \$\endgroup\$ – Zgarb Jun 15 '16 at 10:31
1
\$\begingroup\$

Pyke, 12 bytes

sQB9T16^*/h/

Try it here!

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

Pyth, 14 bytes

csQhc*FQ*9^T16

Test suite.

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

Bonus: click here!

\$\endgroup\$
  • 5
    \$\begingroup\$ It's really unnecessary to include "FGITW" on every solution that is the first on a challenge. \$\endgroup\$ – Mego Jun 14 '16 at 8:50
  • \$\begingroup\$ Sorry, I have deleted it. \$\endgroup\$ – Leaky Nun Jun 14 '16 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\$
  • \$\begingroup\$ Would v=>u=>(v+u)/(1+v*u/9e16) be ok? \$\endgroup\$ – Leaky Nun Jun 14 '16 at 9:08
  • \$\begingroup\$ @LeakyNun yes it would according to this meta post \$\endgroup\$ – Patrick Roberts Jun 14 '16 at 9:56
1
\$\begingroup\$

Julia, 22 bytes

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

Try it online!

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

TI-BASIC, 12 bytes

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

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

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

ForceLang, 116 bytes

Noncompeting, uses language functionality added after the challenge was posted.

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

TI-Basic, 21 bytes

Prompt U,V:(U+V)/(1+UV/9ᴇ16
\$\endgroup\$
  • \$\begingroup\$ Isn't the E worth 2 bytes? \$\endgroup\$ – Leaky Nun Jun 14 '16 at 22:09
  • 3
    \$\begingroup\$ Please check for yourself first... tibasicdev.wikidot.com/e-ten \$\endgroup\$ – Timtech Jun 14 '16 at 22:13
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\$
  • 3
    \$\begingroup\$ You need c^2 in the denominator ... i.e., 9e16 or equivalent. \$\endgroup\$ – AdmBorkBork Jun 14 '16 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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.