Normalize a Vector

To normalize a vector is to scale it to a length of 1 (a unit vector), whilst keeping the direction consistent.

For example, if we wanted to normalize a vector with 3 components, u, we would first find its length:

|u| = sqrt(ux2 + uy2 + uz2)

...and then scale each component by this value to get a length 1 vector.

û = u ÷ |u|

The Challenge

Your task is to write a program or function which, given a non-empty list of signed integers, interprets it as a vector, and normalizes it. This should work for any number of dimensions, for example (test cases rounded to two decimal places):

[20]           -> [1]
[-5]           -> [-1]
[-3, 0]        -> [-1, 0]
[5.5, 6, -3.5] -> [0.62, 0.68, -0.40]
[3, 4, -5, -6] -> [0.32, 0.43, -0.54, -0.65]
[0, 0, 5, 0]   -> [0, 0, 1, 0]


Rules:

• You can assume the input list will:
• Have at least one non-zero element
• Only contain numbers within your language's standard floating point range
• Your output should be accurate to at least two decimal places. Returning "infinite precision" fractions / symbolic values is also allowed, if this is how your language internally stores the data.
• Submissions should be either a full program which performs I/O, or a function. Function submissions can either return a new list, or modify the given list in place.
• Builtin vector functions/classes are allowed. Additionally, if your language has a vector type which supports an arbitrary number of dimensions, you can take one of these as input.

This is a contest, so you should aim to achieve the shortest solution possible (in bytes).

• Does it have to have at least two decimal places for every possible input (which is not possible for any standard type of floating point values) or only for the examples you provide? E.g. Steadybox's answer provides 2 decimal places of precision for all your test but he uses ints for the sum of squares which of course fails for almost all inputs (e.g. [0.1, 0.1]). Nov 27, 2017 at 11:07
• ... now we just wait for a lang with built-in norm function mapped to one char...
– user18967
Nov 27, 2017 at 13:55
• It should be to at least 2dp for every possible input @Christoph Nov 27, 2017 at 16:09
• @FlipTack but that rules out basically all languages because floatings points have bigger exponents than mantissa which means they do not always have enough precision to have any decimal places. Nov 27, 2017 at 19:34
• Why don't the 6 in the 4th example and the -6 in the 5th respectively normalize to 1 and -1?
– Mast
Nov 28, 2017 at 13:03

05AB1E, 4 bytes

Code:

nOt/


Try it online!

Explanation

n     # Square each element of the input
O    # Sum all elements
t   # Take the square root of the sum
/  # Divide each element by the square root of the sum

• n0t what I expected /
– YSC
Nov 27, 2017 at 10:19

JavaScript (ES6), 31 bytes

a=>a.map(n=>n/Math.hypot(...a))


Test cases

let f =

a=>a.map(n=>n/Math.hypot(...a))

console.log(JSON.stringify(f([20]          ))) // -> [1]
console.log(JSON.stringify(f([-5]          ))) // -> [-1]
console.log(JSON.stringify(f([-3, 0]       ))) // -> [-1, 0]
console.log(JSON.stringify(f([5.5, 6, -3.5]))) // -> [0.62, 0.68, -0.40]
console.log(JSON.stringify(f([3, 4, -5, -6]))) // -> [0.32, 0.43, -0.54, -0.65]
console.log(JSON.stringify(f([0, 0, 5, 0]  ))) // -> [0, 0, 1, 0]

Mathematica, 9 bytes

Normalize


Try it online!

• Or #/Norm@#& for the same byte count. Nov 26, 2017 at 22:03

J, 8 bytes

%+/&.:*:


Try it online!

6 bytes %|@j./ works if the vector is at least 2-dimensional.

• Love the way of getting the magnitude.
– cole
Nov 26, 2017 at 22:54
• @cole 1 byte longer: %1%:@#.*: Nov 27, 2017 at 4:10
• Could you please add an explanation for the uninitiated in J? Nov 27, 2017 at 7:49
• % (divide by) +/ (sum) &.: (under) *: (square). + sums two things. +/ sums a list of things. &.: modifies the preceding operation by applying the following operation first and its inverse afterwards. % normally takes two arguments, but (% f) is a function from x to x % (f x). Most operators automagically work on lists. Nov 28, 2017 at 21:20
• And by the same principles, the function that “normalizes” a vector by adding such a number to each component that they sum to zero is “- +/ % #”. Nov 28, 2017 at 21:26

Jelly, 5 3 bytes

÷ÆḊ


Try it online!, or see the test suite

Saved 2 bytes thanks to miles!

• 3 bytes with ÷ÆḊ Nov 26, 2017 at 23:46
• @miles Huh, never knew about that builtin. Thanks Nov 27, 2017 at 0:12
• unfortunately that built-in gives +ve mod for scalars per TIO examplelike absolute value .. the problem requested keeping the sign May 1, 2018 at 15:34

Octave, 13 bytes

@(x)x/norm(x)


Try it online!

C,  73  70 bytes

Thanks to @Christoph for saving a byte!

s,i;f(v,n)float*v;{for(s=0;i++<n;)s+=*v**v++;for(;--i;)*--v/=sqrt(s);}


Try it online!

• +1. s=0,i=0 instead of s=i=0 saves one Nov 27, 2017 at 6:10
• I love the use of s[-i]but sadly *--v/=sqrt(s); is 1 byte shorter. Nov 27, 2017 at 11:08
• @xanoetux Thanks, but I need to initialize the variables inside the function, because functions need to be reusable. Besides, as global variables, s and i are automatically initialized to 0. (Turns out I don't need to initialize i in the function, because the function always leaves it at value 0) Nov 27, 2017 at 11:30
• @Christoph Thanks! I was initially printing the values from the function, so I needed v[-i] to get the values in correct order. Nov 27, 2017 at 11:31

Python, 47 46 bytes

lambda v:[e/sum(e*e for e in v)**.5for e in v]


Try it online!

Julia, 9 bytes

normalize


Try it online!

CJam, 9 bytes

{_:mhzf/}


Try it online!

Explanation

_    e# Duplicate input.
:mh  e# Fold hypothenuse-length over the vector. This gives the norm, unless the vector
e# has only one component, in which case it just gives that component.
z    e# Abs. For the case of a single negative vector component.
f/   e# Divide each vector component by the norm.


TI-Basic, 6 bytes

Ans/√(sum(Ans2

Run with {1,2,3}:prgmNAME, where {1,2,3} is the vector to be normalized.

Divides each element in the vector by the square root of the sum of the squares of its elements.

• We got the same answer! Nov 27, 2017 at 3:24
• @kamoroso94 Whoops! Didn't see yours when I posted this. If you want to add the explanation from this to your answer I'll delete this. Nov 27, 2017 at 3:30
• Nah I'll just remove mine. You put more effort into your answer :P Nov 27, 2017 at 5:48

R, 23 bytes

function(v)v/(v%*%v)^.5


Try it online!

v%*%v computes the dot product of v with itself.
The function will issue a warning for length 2 or greater vectors.

Java (OpenJDK 8), 57 bytes

v->v.stream().map(x->x/v.stream().reduce(0d,Math::hypot))


Try it online!

MATL, 5 bytes

t2&|/


Try it online!

I'm not entirely sure this is the shortest way to do this. First, we duplicate the input, then select the second output type of | (which is either abs, norm or determinant). Finally, we divide the input by the norm.

Alternative for 7 bytes:

t2^sX^/


Haskell, 29 bytes

f x=map(/sqrt(sum$(^2)<$>x))x


Try it online!

Or for 1 byte more pointfree: map=<<flip(/).sqrt.sum.map(^2)

Funky, 42 bytes

a=>(d=a::map)(c=>c/d(b=>b^2)::reduce@+^.5)


Try it online!

Ohm v2, 5 bytes

D²Σ¬/


Try it online!

C++ (gcc), 70 bytes

Input by std::valarray<float>. Overwrites the original vector.

#import<valarray>
int f(std::valarray<float>&a){a/=sqrt((a*a).sum());}


Try it online!

• I am just lurking codegolf every now and then, but isn't this invalid C++, given "#import", which is a Microsoft specific extension? Nov 27, 2017 at 11:01
• @phresnel #import works at least with GCC, Clang and MinGW, too. But, yeah, it's not standard C++. Nov 27, 2017 at 11:36
• @phresnel I forgot to specify gcc. Fixed. Nov 27, 2017 at 12:30

Common Lisp, 69 bytes

(lambda(v)(mapcar(lambda(x)(/ x(sqrt(loop as y in v sum(* y y)))))v))


Try it online!

APL (Dyalog), 1312 10 bytes

1 byte saved thanks to @Adám

2 bytes saved thanks to @ngn

⊢÷.5*⍨+.×⍨


Try it online!

How?

⊢  ÷  .5*⍨  +.  ×⍨
u  ÷    √   Σ   u²

• Train for less: ⊢÷.5*⍨(+/×⍨)
– Adám
Nov 26, 2017 at 22:15
• @Adám thanks alot! I've been trying for hours, couldn't get any train to work Nov 26, 2017 at 22:27
• We should do something about that, as it is really not so hard. When you have a monadic function (other than the rightmost one), begin a parenthesis to its left (or use a ∘ if it isn't derived). Other than that, just swap ⍺ and ⍵ for ⊣ and ⊢: {⍵÷.5*⍨+/×⍨⍵}{⍵÷.5*⍨(+/(×⍨⍵))}⊢÷.5*⍨(+/(×⍨⊢))⊢÷.5*⍨(+/(×⍨))⊢÷.5*⍨(+/×⍨)
– Adám
Nov 27, 2017 at 10:13
• (+/×⍨) -> +.×⍨
– ngn
Nov 28, 2017 at 7:15

Husk, 8 7 bytes

´(Ṁ/√ṁ□


Try it online!

C# (.NET Core), 51+64=115 bytes

v=>v.Select(d=>d/Math.Sqrt(v.Select(x=>x*x).Sum()))


Try it online!

+64 bytes for the using System;using System.Collections.Generic;using System.Linq;

C# (.NET Core), 94+13=107 bytes

v=>{var m=0d;foreach(var x in v)m+=x*x;for(int i=0;i<v.Length;)v[i++]/=Math.Sqrt(m);return v;}


Try it online!

+13 bytes for using System;

The non-Linq approach

DeGolfed

v=>{
var m=0d;
foreach (var x in v)
m+=x*x;

for (int i=0; i < v.Length;)
v[i++] /= Math.Sqrt(m);

return v;
}


Perl 5, 45 + 1 (-a) = 46 bytes

say$_/sqrt eval join'+',map"($_)**2",@F for@F


Try it online!

Pip, 10 bytes

9 bytes of code, +1 for -p flag.

g/RT$+g*g  Takes the vector as separate command-line arguments. Try it online! How it works  g*g Arglist, multiplied by itself itemwise$+     Sum
RT       Square root
g/         Divide arglist itemwise by that scalar
Result is autoprinted (-p flag to format as list)


Pyth, 5 bytes

cR.aQ


Try it online: Test Suite

Explanation:

cR.aQQ   implicit Q at the end
c        divide
R   Q   each element of the input
.aQ    by the L2 norm of the input vector


Perl 6, 25 bytes

{$_ »/»sqrt sum$_»²}


Try it online!

$_, the list argument to the function, is divided elementwise (»/») by the square root of the sum of the squares of the elements (»²). Ruby, 39 35 bytes ->v{v.map{|x|x/v.sum{|x|x*x}**0.5}}  -4 bytes thanks to G B. • Save some bytes by using sum{...} instead of map{...}.sum – G B Nov 27, 2017 at 11:34 APL NARS 12 Characters f←{⍵÷√+/⍵*2}  • You don't have to count f← in your byte count, since you can use the dfns without it. By the way, is √ a single byte in NARS? I'm not familiar with it, so just asking Nov 26, 2017 at 22:48 • @Uriel Nars Apl in the few I know would write with Unicode so number of bytes should be 12x2 – user58988 Nov 27, 2017 at 6:01 Google Sheets, 65 bytes =ArrayFormula(TextJoin(",",1,If(A:A="","",A:A/Sqrt(Sumsq(A:A)))))  The input list is in column A with one entry per cell. This is how spreadsheets would normally use lists. Unfortunately, this would normally result in a long list of ,0,0,0,0,0,.... at the end so we have to ignore those with the If Blank then Blank else Math logic. If it was all in one cell, instead, the solution would be 95 bytes: =ArrayFormula(TextJoin(",",1,If(Split(A1,",")="","",Split(A1,",")/Sqrt(Sumsq(Split(A1,","))))))  Swift 4, 44 bytes {a in a.map{$0/sqrt(a.reduce(0){$0+$1*\$1})}}


Recalculates the vector norm for every component, but at least it's terse!