Menormalkan Vektor


28

Untuk menormalkan suatu vektor berarti menskalakannya menjadi panjang 1 ( vektor satuan ), sambil menjaga arahnya konsisten.

Misalnya, jika kita ingin menormalkan vektor dengan 3 komponen, u , pertama-tama kita akan menemukan panjangnya:

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

... dan kemudian skala setiap komponen dengan nilai ini untuk mendapatkan vektor panjang 1.

û = u ÷ | u |


Tantangan

Tugas Anda adalah menulis sebuah program atau fungsi yang, mengingat daftar bilangan bulat yang tidak kosong, menafsirkannya sebagai vektor, dan menormalkannya. Ini harus bekerja untuk sejumlah dimensi, misalnya (kasus uji dibulatkan ke dua tempat desimal):

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

Aturan:

  • Anda dapat mengasumsikan daftar input akan:
    • Memiliki setidaknya satu elemen yang tidak nol
    • Hanya berisi angka dalam rentang titik mengambang standar bahasa Anda
  • Output Anda harus akurat untuk setidaknya dua tempat desimal . Mengembalikan nilai fraksi / nilai simbolik "presisi tak terbatas" juga diperbolehkan, jika ini adalah cara bahasa Anda menyimpan data secara internal.
  • Pengajuan harus berupa program lengkap yang menjalankan I / O, atau suatu fungsi. Pengajuan fungsi dapat mengembalikan daftar baru, atau mengubah daftar yang diberikan di tempat.
  • Fungsi / kelas vektor bawaan diizinkan. Selain itu, jika bahasa Anda memiliki jenis vektor yang mendukung jumlah dimensi yang berubah-ubah, Anda dapat mengambil salah satunya sebagai input.

Ini adalah kontes , jadi Anda harus berusaha mencapai solusi sesingkat mungkin (dalam byte).


Apakah harus memiliki setidaknya dua tempat desimal untuk setiap input yang mungkin (yang tidak mungkin untuk jenis standar nilai floating point) atau hanya untuk contoh yang Anda berikan? Misalnya jawaban Steadybox memberikan 2 tempat desimal presisi untuk semua pengujian Anda, tetapi ia menggunakan ints untuk jumlah kuadrat yang tentu saja gagal untuk hampir semua input (mis. [0,1, 0,1]).
Christoph

... sekarang kita tunggu saja lang dengan fungsi norma
bawaan yang

Seharusnya minimal 2dp untuk setiap input yang mungkin
@Christoph

@FlipTack tetapi itu mengesampingkan pada dasarnya semua bahasa karena titik apung memiliki eksponen yang lebih besar daripada mantissa yang berarti mereka tidak selalu memiliki presisi yang cukup untuk memiliki tempat desimal.
Christoph

Mengapa 6 pada contoh ke-4 dan -6 di ke-5 tidak dinormalisasi menjadi 1 dan -1?
Tiang

Jawaban:


15

05AB1E , 4 byte

Kode:

nOt/

Cobalah online!

Penjelasan

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

9
bukan apa yang saya harapkan /
YSC

10

JavaScript (ES6), 31 byte

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

Uji kasus



9

J , 8 byte

%+/&.:*:

Cobalah online!

6 byte %|@j./berfungsi jika vektor setidaknya 2 dimensi .


Cinta cara mendapatkan besarnya.
cole

1
@cole 1 byte lebih lama:%1%:@#.*:
FrownyFrog

6
Bisakah Anda menambahkan penjelasan untuk yang belum tahu di J?
MechMK1

% (dibagi dengan) + / (jumlah) & .: (di bawah) *: (persegi). + menjumlahkan dua hal. + / menjumlahkan daftar hal-hal. & .: memodifikasi operasi sebelumnya dengan menerapkan operasi berikut terlebih dahulu dan kebalikannya setelahnya. % biasanya mengambil dua argumen, tetapi (% f) adalah fungsi dari x ke x% (fx). Sebagian besar operator secara otomatis bekerja pada daftar.
Roman Odaisky

Dan dengan prinsip yang sama, fungsi yang "menormalkan" vektor dengan menambahkan angka sedemikian rupa ke setiap komponen yang dijumlahkan menjadi nol adalah "- + /% #".
Roman Odaisky



6

C,  73  70 byte

Terima kasih kepada @Christoph karena telah menghemat satu byte!

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

Cobalah online!


+1. s=0,i=0bukannya s=i=0menghemat satu
xanoetux

Saya suka menggunakan s[-i]tetapi sayangnya *--v/=sqrt(s);1 byte lebih pendek.
Christoph

1
@xanoetux Terima kasih, tapi saya perlu menginisialisasi variabel di dalam fungsi, karena fungsi harus dapat digunakan kembali . Selain itu, sebagai variabel global, sdan isecara otomatis diinisialisasi ke 0. (Ternyata saya tidak perlu menginisialisasi idalam fungsi, karena fungsi selalu meninggalkannya pada nilai 0)
Steadybox

1
@Christoph Terima kasih! Saya awalnya mencetak nilai-nilai dari fungsi, jadi saya harus v[-i]mendapatkan nilai-nilai dalam urutan yang benar.
Steadybox



3

CJam , 9 byte

{_:mhzf/}

Cobalah online!

Penjelasan

_    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-Basic, 6 byte

Ans/√(sum(Ans2

Jalankan dengan {1,2,3}:prgmNAME, di mana {1,2,3}vektor dinormalisasi.

Membagi setiap elemen dalam vektor dengan akar kuadrat dari jumlah kuadrat elemennya.


Kami mendapat jawaban yang sama!
kamoroso94

@ kamoroso94 Whoops! Tidak melihat Anda ketika saya memposting ini. Jika Anda ingin menambahkan penjelasan dari ini ke jawaban Anda, saya akan menghapus ini.
pizzapants184

Nah saya hanya akan menghapus milik saya. Anda lebih berupaya dalam jawaban Anda: P
kamoroso94

3

R , 23 byte

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

Cobalah online!

v%*%vmenghitung titik produk v dengan dirinya sendiri.
Fungsi ini akan mengeluarkan peringatan untuk vektor dengan panjang 2 atau lebih besar.



2

MATL , 5 byte

t2&|/

Cobalah online!

Saya tidak sepenuhnya yakin ini adalah cara terpendek untuk melakukan ini. Pertama, kita menduplikasi input, lalu pilih tipe output kedua |(yang mana adalah abs, normatau determinant). Akhirnya, kami membagi input dengan norma.

Alternatif untuk 7 byte:

t2^sX^/




2

C ++ (gcc), 70 byte

Masukan oleh std::valarray<float>. Menimpa vektor asli.

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

Cobalah online!


Saya hanya mengintai codegolf setiap saat, tetapi bukankah ini C + + tidak valid, diberi "#import", yang merupakan ekstensi spesifik Microsoft?
phresnel

@phresnel #importbekerja setidaknya dengan GCC, Dentang dan MinGW juga. Tapi, ya, itu bukan standar C ++.
Steadybox

@ saluran Saya lupa menentukan gcc. Tetap.
Colera Su


2

APL (Dyalog) , 13 12 10 byte

1 byte disimpan berkat @ Adám

2 byte disimpan berkat @ngn

⊢÷.5*⍨+.×⍨

Cobalah online!

Bagaimana?

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

Latih kurang:⊢÷.5*⍨(+/×⍨)
Adám

@ Adam terima kasih banyak! Saya sudah berusaha selama berjam-jam, tidak bisa mendapatkan kereta untuk bekerja
Uriel

Kita harus melakukan sesuatu tentang itu, karena ini tidak terlalu sulit. Ketika Anda memiliki fungsi monadik (selain yang paling kanan), mulailah tanda kurung di sebelah kirinya (atau gunakan jika itu tidak diturunkan). Selain itu, cukup tukar dan untuk dan : {⍵÷.5*⍨+/×⍨⍵}{⍵÷.5*⍨(+/(×⍨⍵))}⊢÷.5*⍨(+/(×⍨⊢))⊢÷.5*⍨(+/(×⍨))⊢÷.5*⍨(+/×⍨)
Adám

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


1

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

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

Cobalah online!

+64 byte untuk using System;using System.Collections.Generic;using System.Linq;

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

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

Cobalah online!

+13 byte untuk using System;

Pendekatan non-Linq

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


1

Pip , 10 byte

9 byte kode, +1 untuk -pbendera.

g/RT$+g*g

Mengambil vektor sebagai argumen baris perintah yang terpisah. Cobalah online!

Bagaimana itu bekerja

      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 byte

cR.aQ

Cobalah online: Test Suite

Penjelasan:

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

Perl 6 , 25 byte

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

Cobalah online!

$_, argumen daftar ke fungsi, dibagi elementwise ( »/») oleh akar kuadrat dari jumlah kuadrat elemen ( »²).


1

Ruby, 39 35 byte

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

-4 byte terima kasih kepada G B.


1
Simpan beberapa byte dengan menggunakan sum{...}sebagai gantinyamap{...}.sum
GB

0

APL NARS 12 Karakter

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

Anda tidak perlu menghitung f← dalam hitungan byte Anda, karena Anda dapat menggunakan dfns tanpa itu. Omong-omong, apakah satu byte tunggal di NARS? Saya tidak terbiasa dengan hal itu, jadi tanyakan saja
Uriel

@Uriel Nars Apl dalam beberapa yang saya tahu akan menulis dengan Unicode sehingga jumlah byte harus 12x2
RosLuP

0

Google Sheets, 65 byte

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

Daftar input ada di kolom Adengan satu entri per sel. Beginilah biasanya spreadsheet menggunakan daftar. Sayangnya, ini biasanya akan menghasilkan daftar panjang ,0,0,0,0,0,....di akhir sehingga kita harus mengabaikan mereka yang memiliki If Blank then Blank else Mathlogika.

Jika semuanya ada dalam satu sel, maka solusinya adalah 95 byte:

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.