29
\$\begingroup\$

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).

\$\endgroup\$
6
  • \$\begingroup\$ 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]). \$\endgroup\$
    – Christoph
    Nov 27, 2017 at 11:07
  • \$\begingroup\$ ... now we just wait for a lang with built-in norm function mapped to one char... \$\endgroup\$
    – user18967
    Nov 27, 2017 at 13:55
  • \$\begingroup\$ It should be to at least 2dp for every possible input @Christoph \$\endgroup\$
    – FlipTack
    Nov 27, 2017 at 16:09
  • \$\begingroup\$ @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. \$\endgroup\$
    – Christoph
    Nov 27, 2017 at 19:34
  • \$\begingroup\$ Why don't the 6 in the 4th example and the -6 in the 5th respectively normalize to 1 and -1? \$\endgroup\$
    – Mast
    Nov 28, 2017 at 13:03

38 Answers 38

15
\$\begingroup\$

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
\$\endgroup\$
1
  • 12
    \$\begingroup\$ n0t what I expected / \$\endgroup\$
    – YSC
    Nov 27, 2017 at 10:19
10
\$\begingroup\$

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]

\$\endgroup\$
10
\$\begingroup\$

Mathematica, 9 bytes

Normalize

Try it online!

\$\endgroup\$
1
  • 13
    \$\begingroup\$ Or #/Norm@#& for the same byte count. \$\endgroup\$ Nov 26, 2017 at 22:03
9
\$\begingroup\$

J, 8 bytes

%+/&.:*:

Try it online!

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

\$\endgroup\$
5
  • \$\begingroup\$ Love the way of getting the magnitude. \$\endgroup\$
    – cole
    Nov 26, 2017 at 22:54
  • 1
    \$\begingroup\$ @cole 1 byte longer: %1%:@#.*: \$\endgroup\$
    – FrownyFrog
    Nov 27, 2017 at 4:10
  • 6
    \$\begingroup\$ Could you please add an explanation for the uninitiated in J? \$\endgroup\$
    – MechMK1
    Nov 27, 2017 at 7:49
  • \$\begingroup\$ % (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. \$\endgroup\$ Nov 28, 2017 at 21:20
  • \$\begingroup\$ 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 “- +/ % #”. \$\endgroup\$ Nov 28, 2017 at 21:26
8
\$\begingroup\$

Jelly, 5 3 bytes

÷ÆḊ

Try it online!, or see the test suite

Saved 2 bytes thanks to miles!

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

Octave, 13 bytes

@(x)x/norm(x)

Try it online!

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

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!

\$\endgroup\$
4
  • \$\begingroup\$ +1. s=0,i=0 instead of s=i=0 saves one \$\endgroup\$
    – caylee
    Nov 27, 2017 at 6:10
  • \$\begingroup\$ I love the use of s[-i]but sadly *--v/=sqrt(s); is 1 byte shorter. \$\endgroup\$
    – Christoph
    Nov 27, 2017 at 11:08
  • 1
    \$\begingroup\$ @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) \$\endgroup\$
    – Steadybox
    Nov 27, 2017 at 11:30
  • 1
    \$\begingroup\$ @Christoph Thanks! I was initially printing the values from the function, so I needed v[-i] to get the values in correct order. \$\endgroup\$
    – Steadybox
    Nov 27, 2017 at 11:31
4
\$\begingroup\$

Python, 47 46 bytes

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

Try it online!

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

Julia, 9 bytes

normalize

Try it online!

\$\endgroup\$
3
\$\begingroup\$

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

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.

\$\endgroup\$
3
  • \$\begingroup\$ We got the same answer! \$\endgroup\$
    – kamoroso94
    Nov 27, 2017 at 3:24
  • \$\begingroup\$ @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. \$\endgroup\$ Nov 27, 2017 at 3:30
  • \$\begingroup\$ Nah I'll just remove mine. You put more effort into your answer :P \$\endgroup\$
    – kamoroso94
    Nov 27, 2017 at 5:48
3
\$\begingroup\$

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.

\$\endgroup\$
3
\$\begingroup\$

Java (OpenJDK 8), 57 bytes

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

Try it online!

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

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^/
\$\endgroup\$
2
\$\begingroup\$

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)

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

Funky, 42 bytes

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

Try it online!

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

Ohm v2, 5 bytes

D²Σ¬/

Try it online!

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

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!

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

Common Lisp, 69 bytes

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

Try it online!

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

APL (Dyalog), 13 12 10 bytes

1 byte saved thanks to @Adám

2 bytes saved thanks to @ngn

⊢÷.5*⍨+.×⍨

Try it online!

How?

⊢  ÷  .5*⍨  +.  ×⍨
u  ÷    √   Σ   u²
\$\endgroup\$
4
  • \$\begingroup\$ Train for less: ⊢÷.5*⍨(+/×⍨) \$\endgroup\$
    – Adám
    Nov 26, 2017 at 22:15
  • \$\begingroup\$ @Adám thanks alot! I've been trying for hours, couldn't get any train to work \$\endgroup\$
    – Uriel
    Nov 26, 2017 at 22:27
  • \$\begingroup\$ 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*⍨(+/×⍨) \$\endgroup\$
    – Adám
    Nov 27, 2017 at 10:13
  • \$\begingroup\$ (+/×⍨) -> +.×⍨ \$\endgroup\$
    – ngn
    Nov 28, 2017 at 7:15
2
\$\begingroup\$

Vyxal, 4 bytes

²∑√/

Try it Online!

²    # Square each
 ∑   # Sum
  √  # Square root
   / # Divide by that
\$\endgroup\$
1
\$\begingroup\$

Husk, 8 7 bytes

´(Ṁ/√ṁ□

Try it online!

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

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

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

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

Try it online!

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

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

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

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 (»²).

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

Ruby, 39 35 bytes

->v{v.map{|x|x/v.sum{|x|x*x}**0.5}}

-4 bytes thanks to G B.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Save some bytes by using sum{...} instead of map{...}.sum \$\endgroup\$
    – G B
    Nov 27, 2017 at 11:34
1
\$\begingroup\$

Coconut, 40 bytes

x->map((/)$(?,sum(map(t->t*t,x))**.5),x)

I have no idea what I'm doing...

Try it online!

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

Thunno D, \$ 5 \log_{256}(96) \approx \$ 4.12 bytes

2^St/

Attempt This Online!

Explanation

2^St/  # D flag duplicates the input
2^     # Square each
  S    # Sum this list
   t   # Push the square root
    /  # Divide the input by this number
\$\endgroup\$

Your Answer

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

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