벡터 정규화


28

벡터 를 정규화 하는 것은 방향을 일관되게 유지하면서 길이를 1 ( 단위 벡터 )로 조정하는 것입니다.

예를 들어 3 개의 성분 u 로 벡터를 정규화하려면 먼저 길이를 찾습니다.

| u | = sqrt (u x 2 + u y 2 + u z 2 )

... 각 값을이 값으로 조정하여 길이 1 벡터를 얻습니다.

û = u ÷ | u |


도전

비어 있지 않은 부호있는 정수 목록을 제공하고 벡터로 해석하여 정규화하는 프로그램이나 함수를 작성해야합니다. 예를 들어 (소수점은 소수점 이하 두 자리로 반올림)과 같이 여러 차원에서 작동합니다.

[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]

규칙 :

  • 입력 목록이 다음과 같이 가정 할 수 있습니다.
    • 0이 아닌 요소가 하나 이상 있어야합니다.
    • 언어의 표준 부동 소수점 범위 내의 숫자 만 포함
  • 출력값은 소수점 이하 두 자리 이상 정확해야합니다 . 언어가 내부적으로 데이터를 저장하는 방법 인 경우 "무한 정밀도"분수 / 기호 값을 반환 할 수도 있습니다.
  • 제출은 I / O를 수행하는 전체 프로그램이거나 기능이어야합니다. 함수 제출은 새 목록을 리턴하거나 주어진 목록을 제자리에서 수정할 수 있습니다.
  • 내장 벡터 함수 / 클래스가 허용됩니다. 또한 언어에 임의의 수의 차원을 지원하는 벡터 유형이있는 경우 이들 중 하나를 입력으로 사용할 수 있습니다.

이것은 경연 대회이므로 가능한 가장 짧은 솔루션 (바이트)을 달성하는 것을 목표로해야합니다.


가능한 모든 입력에 대해 소수점 이하 두 자리 이상 (표준 유형의 부동 소수점 값에서는 불가능) 또는 제공 한 예제에만 있어야합니까? 예를 들어 Steadybox의 답변은 모든 테스트에 소수점 이하 2 자리의 정밀도를 제공하지만 거의 모든 입력에 대해 실패하는 제곱의 합에 정수를 사용합니다 (예 : [0.1, 0.1]).
Christoph

... 이제 우리는 하나의 문자에 매핑 된 내장 함수가있는 언어를 기다립니다 ...
vaxquis

가능한 모든 입력에 대해 적어도 2dp 여야합니다. @Christoph
FlipTack

@FlipTack 그러나 부동 소수점은 가수보다 지수가 크기 때문에 기본적으로 모든 언어를 배제합니다. 즉, 소수점 이하 자릿수를 가질 수있는 정밀도가 항상 충분하지는 않습니다.
Christoph

4 번째 예의 6과 5 위의 -6이 각각 1과 -1로 정규화되지 않는 이유는 무엇입니까?
Mast

답변:



10

자바 스크립트 (ES6), 31 바이트

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

테스트 사례



9

J , 8 바이트

%+/&.:*:

온라인으로 사용해보십시오!

벡터가 2 차원 이상이면 6 바이트가 %|@j./작동 합니다 .


규모를 얻는 방법을 좋아하십시오.
cole

1
@cole 1 바이트 이상 :%1%:@#.*:
FrownyFrog 4:27에

6
시작되지 않은 J에 대한 설명을 추가해 주시겠습니까?
MechMK1 1

% (나누기) + / (sum) & .: (under) * : (square). +는 두 가지를 요약합니다. + /는 사물의 목록을 합칩니다. & .: 다음 작업을 먼저 적용한 후 그 역을 적용하여 이전 작업을 수정합니다. %는 일반적으로 두 개의 인수를 취하지 만 (% f)는 x에서 x % (fx)까지의 함수입니다. 대부분의 연산자는 목록에서 자동으로 작업합니다.
Roman Odaisky

같은 원리로, 벡터에 합산되는 숫자를 0으로 더하여 벡터를 "정규화"하는 기능은 "-+ / % #"입니다.
Roman Odaisky

8

젤리 , 5 3 바이트

÷ÆḊ

온라인으로 사용해보십시오! 또는 테스트 스위트를 참조하십시오

마일 덕분에 2 바이트를 절약했습니다!


÷ÆḊ
마일을

@ 마일즈 허, 그 내장에 대해 전혀 몰랐습니다. 덕분에
coinheringaahing 케어 드

불행하게도 내장 된 것을 +는 TIO 당 스칼라에 대한 모드를했습니다주는 절대 값을 examplelike .. 문제는 기호를 유지 요청
jayprich


6

C,  73  70 바이트

바이트를 저장해 준 @Christoph에게 감사합니다!

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

온라인으로 사용해보십시오!


+1. s=0,i=0대신이 s=i=0하나의 저장
xanoetux

나는 사용을 사랑 s[-i]하지만 슬프게도 *--v/=sqrt(s);1 바이트가 짧습니다.
Christoph

1
@xanoetux 감사하지만 함수를 재사용 할 수 있어야하기 때문에 함수 내부의 변수를 초기화 해야합니다 . 게다가, 글로벌 변수로, s그리고 i(I 초기화 할 필요가 없습니다 밝혀 자동으로 0으로 초기화 i함수에서 함수는 항상 값 0을 잎 때문에)
Steadybox

1
@Christoph 감사합니다! 처음에는 함수에서 값을 인쇄하고 있었으므로 v[-i]올바른 순서로 값을 가져와야했습니다.
Steadybox



3

CJam , 9 바이트

{_:mhzf/}

온라인으로 사용해보십시오!

설명

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

3

TI 기본, 6 바이트

Ans/√(sum(Ans2

와 실행 {1,2,3}:prgmNAME, 어디는 {1,2,3}벡터가 정상화하는 것입니다.

벡터의 각 요소를 해당 요소의 제곱의 합의 제곱근으로 나눕니다.


우리는 같은 대답을 얻었다!
kamoroso94

트윗 담아 가기 내가 이것을 게시했을 때 당신을 보지 못했습니다. 이 설명을 답변에 추가하려면이 설명을 삭제합니다.
pizzapants184

아냐, 난 그냥 내꺼를 제거합니다. P : 당신은 당신의 대답에 더 많은 노력을
kamoroso94



2

MATL , 5 바이트

t2&|/

온라인으로 사용해보십시오!

이것이 가장 짧은 방법인지 확실하지 않습니다. 먼저, 다음의 입력을 중복의 제 2 출력 타입을 선택 |(하나 인 abs, normdeterminant). 마지막으로 입력을 표준으로 나눕니다.

7 바이트의 대안 :

t2^sX^/




2

C ++ (gcc), 70 바이트

님이 입력했습니다 std::valarray<float>. 원래 벡터를 덮어 씁니다.

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

온라인으로 사용해보십시오!


나는 때때로 codegolf를 숨기고 있지만 "#import"라는 Microsoft C ++의 잘못된 C ++이 아닌가?
phresnel

@phresnel #import은 최소한 GCC, Clang 및 MinGW에서도 작동합니다. 그러나 표준 C ++이 아닙니다.
Steadybox

@phresnel gcc를 지정하는 것을 잊었습니다. 결정된.
Colera Su


2

APL (Dyalog) , 13 12 10 바이트

@ Adám 덕분에 1 바이트 절약

@ngn 덕분에 2 바이트 절약

⊢÷.5*⍨+.×⍨

온라인으로 사용해보십시오!

방법?

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

덜 훈련 :⊢÷.5*⍨(+/×⍨)
Adám

@ Adám 감사합니다! 몇 시간 동안 노력했지만 기차를 타지 못했습니다
Uriel

실제로 그렇게 어렵지 않기 때문에 우리는 그것에 대해 무언가를해야합니다. 가장 오른쪽이 아닌 monadic 함수가있는 경우 왼쪽에 괄호를 시작하십시오 (또는 파생되지 않은 경우 사용 ). , 그 외에는 단지 스왑 대한 : {⍵÷.5*⍨+/×⍨⍵}{⍵÷.5*⍨(+/(×⍨⍵))}⊢÷.5*⍨(+/(×⍨⊢))⊢÷.5*⍨(+/(×⍨))⊢÷.5*⍨(+/×⍨)
아담

(+/×⍨)->+.×⍨
ngn


1

C # (. NET 코어) , 51 + 64 = 115 바이트

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

온라인으로 사용해보십시오!

+64 바이트 using System;using System.Collections.Generic;using System.Linq;

C # (. NET 코어) , 94 + 13 = 107 바이트

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;}

온라인으로 사용해보십시오!

+13 바이트 using System;

비 Linq 접근 방식

골프

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;
}


1

, 10 바이트

9 바이트의 코드, -p플래그의 경우 +1

g/RT$+g*g

벡터를 별도의 명령 줄 인수로 사용합니다. 온라인으로 사용해보십시오!

작동 원리

      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)

1

Pyth, 5 바이트

cR.aQ

온라인 사용해보기 : Test Suite

설명:

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


1

루비, 39 35 바이트

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

G B 덕분에 -4 바이트


1
사용하여 일부 바이트를 저장 sum{...}하는 대신map{...}.sum
GB

0

APL NARS 12 자

f←{⍵÷√+/⍵*2}

f← 바이트 수 를 계산할 필요는 없습니다. 바이트 수없이 dfn을 사용할 수 있기 때문입니다. 그건 그렇고, NARS의 단일 바이트입니까? 나는 그것에 익숙하지 않다. 그냥 묻는다
Uriel

@Uriel Nars Apl은 유니 코드로 쓸 것이므로 바이트 수는 12x2가되어야합니다.
RosLuP

0

Google 스프레드 시트, 65 바이트

=ArrayFormula(TextJoin(",",1,If(A:A="","",A:A/Sqrt(Sumsq(A:A)))))

입력 목록은 A셀당 하나의 항목 이있는 열에 있습니다. 스프레드 시트가 일반적으로 목록을 사용하는 방식입니다. 불행히도, 이것은 일반적으로 ,0,0,0,0,0,....끝에 긴 목록을 초래 하므로 우리는If Blank then Blank else Math 논리를 .

모두 하나의 셀에 있으면 솔루션은 95 바이트입니다.

=ArrayFormula(TextJoin(",",1,If(Split(A1,",")="","",Split(A1,",")/Sqrt(Sumsq(Split(A1,","))))))

0

스위프트 4, 44 바이트

{a in a.map{$0/sqrt(a.reduce(0){$0+$1*$1})}}

모든 구성 요소에 대한 벡터 표준을 다시 계산하지만 최소한 간결합니다!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.