ベクトルを正規化する


28

ベクトルを正規化するとは、方向を一定に保ちながら、長さ1(単位ベクトル)にスケーリングすることです。

たとえば、3つの成分uでベクトルを正規化する場合、最初にその長さを見つけます。

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

...次に、各コンポーネントをこの値でスケーリングして、長さ1のベクトルを取得します。

û= u÷| u |


チャレンジ

あなたの仕事は、署名された整数の空でないリストを与えられ、それをベクトルとして解釈し、それを正規化するプログラムまたは関数を書くことです。これは、たとえば、任意の数のディメンションで機能するはずです(テストケースを小数点以下2桁に丸める)。

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

ルール:

  • 入力リストは次のようになります。
    • 少なくとも1つの非ゼロ要素がある
    • 言語の標準浮動小数点範囲内の数字のみを含む
  • 出力は、少なくとも 小数点以下2桁まで正確でなければなりません。言語がデータを内部的に保存する方法であれば、「無限精度」の小数/記号値を返すこともできます。
  • 提出は、I / Oを実行する完全なプログラム、または機能のいずれかでなければなりません。関数を送信すると、新しいリストが返されるか、所定のリストが変更されます。
  • 組み込みのベクトル関数/クラスが許可されています。さらに、言語に任意の次元数をサポートするベクトル型がある場合、これらのいずれかを入力として使用できます。

これはコンテストですので、可能な限り最短のソリューション(バイト単位)を達成することを目指してください。


可能なすべての入力(標準タイプの浮動小数点値では不可能)または指定した例のみに少なくとも2桁の小数点以下が必要ですか?たとえば、Steadyboxの答えは、すべてのテストで小数点以下2桁の精度を提供しますが、2乗の合計にintを使用しますが、ほとんどすべての入力で失敗します(たとえば[0.1、0.1])。
クリストフ

...ここで、1つの文字にマップされた組み込みのノルム関数を含むlangを待ちます
...-vaxquis

すべての可能な入力に対して少なくとも2dpである必要があります@Christoph
FlipTack

@FlipTackですが、浮動小数点は仮数よりも大きな指数を持つため、基本的にすべての言語が除外されます。つまり、小数点以下の桁数を確保するのに十分な精度があるとは限りません。
クリストフ

4番目の例の6と5番目の-6がそれぞれ1と-1に正規化しないのはなぜですか?
マスト

回答:



10

JavaScript(ES6)、31バイト

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

テストケース



9

J、8バイト

%+/&.:*:

オンラインでお試しください!

ベクトルが少なくとも2次元の場合、 6バイトが%|@j./機能します。


大きさを取得する方法が大好きです。
コール

1
@cole 1バイト長い:%1%:@#.*:
FrownyFrog

6
Jの未経験者の説明を追加してください。
MechMK1

%(除算)+ /(合計)&.:(下)*:(四角)。+ 2つのことを合計します。+ /物のリストを合計します。&.:次の操作を最初に適用し、その後にその逆を適用することにより、前の操作を変更します。%は通常2つの引数を取りますが、(%f)はxからx%(fx)の関数です。ほとんどのオペレーターは自動的にリストを操作します。
ロマンオダイスキー

また、同じ原理により、各コンポーネントにゼロになるような数を加算することによりベクトルを「正規化」する関数は「-+ /%#」です。
ロマンオダイスキー

8

ゼリー5 3バイト

÷ÆḊ

オンラインでお試しください!、またはテストスイートを見る

マイルのおかげで2バイト節約できました!


3バイト÷ÆḊ
マイル

@miles Huh、その組み込みを知らなかった。おかげで
ケアニコインヘリング

残念ながら、内蔵のこと+はTIOあたりスカラーのためのmod VEの与え絶対値を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。1 s=0,i=0s=i=0保存する代わりに
-xanoetux

の使用は大好きですs[-i]が、悲しいこと*--v/=sqrt(s);に1バイト短くなっています。
クリストフ

1
@xanoetuxありがとう。ただし、関数は再利用可能である必要があるため、関数内の変数を初期化する必要があります。また、グローバル変数として、si(私は初期化する必要はありませんが判明し、自動的に0に初期化されているi関数内で関数は常に値0でそれを残しているため、)
Steadybox

1
@Christophありがとう!最初は関数から値を出力していたのでv[-i]、値を正しい順序で取得する必要がありました。
Steadybox




3

TI-Basic、6バイト

Ans/√(sum(Ans2

で実行します{1,2,3}:prgmNAME。ここで、{1,2,3}は正規化されるベクトルです。

ベクトルの各要素を、その要素の平方和の平方根で除算します。


同じ答えを得た!
kamoroso94

@ kamoroso94おっと!私がこれを投稿したときにあなたのものを見ませんでした。この説明を回答に追加する場合は、これを削除します。
pizzapants184

いや、私は私のものを削除します。あなたの答えにより多くの努力を注ぐ:P
kamoroso94







2

C ++(gcc)、70バイト

による入力std::valarray<float>。元のベクトルを上書きします。

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

オンラインでお試しください!


私は時々codegolfに潜んでいますが、Microsoft固有の拡張機能である "#import"が指定されているこの無効なC ++ではないでしょうか。
フレネル

@phresnel #importは、少なくともGCC、Clang、MinGWでも動作します。しかし、そう、それは標準のC ++ではありません。
Steadybox

@phresnel gccを指定するのを忘れました。一定。
コレラSu


2

APL(Dyalog)13 12 10バイト

@Adámのおかげで1バイト節約

@ngnのおかげで2バイト節約

⊢÷.5*⍨+.×⍨

オンラインでお試しください!

どうやって?

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

少ないための訓練:⊢÷.5*⍨(+/×⍨)
アダム

@Adámありがとう!私は何時間も試してみましたが、電車を
Uriel

それは本当にそれほど難しくないので、私たちはそれについて何かをする必要があります。モナド関数(右端以外)がある場合は、その左から括弧を開始します(または、派生していない場合はaを使用します)。、それ以外は単にスワップため{⍵÷.5*⍨+/×⍨⍵}{⍵÷.5*⍨(+/(×⍨⍵))}⊢÷.5*⍨(+/(×⍨⊢))⊢÷.5*⍨(+/(×⍨))⊢÷.5*⍨(+/×⍨)
アダム・

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


1

C#(.NET Core)、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 Core)、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

オンラインで試す:テストスイート

説明:

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← dfnsはバイトカウントなしで使用できるため、バイトカウントをカウントする必要はありません。ちなみに、NARSの1バイトはありますか?私はそれに慣れていないよ、これだけ尋ねる
ウリエル

バイト数は12x2でなければなりませんので、いくつかのIのノウハウで@UrielナーズAPLは、Unicodeで書くでしょう
RosLuP

0

Googleスプレッドシート、65バイト

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

入力リストは列にありA、セルごとに1つのエントリがあります。これは、スプレッドシートが通常リストを使用する方法です。残念ながら、これは通常,0,0,0,0,0,....、最後に長いリストになるため、If Blank then Blank else Mathロジックを持つものを無視する必要があります。

代わりにすべてが1つのセルにある場合、ソリューションは95バイトになります。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.