Bình thường hóa một Vector


28

Để chuẩn hóa một vectơ là chia tỷ lệ thành 1 ( vectơ đơn vị ), trong khi vẫn giữ hướng nhất quán.

Ví dụ, nếu chúng ta muốn bình thường hóa một vector với 3 thành phần, u , chúng tôi sẽ lần đầu tiên tìm thấy chiều dài của nó:

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

... Và sau đó chia tỷ lệ từng thành phần theo giá trị này để có được một vectơ có độ dài 1.

û = u ÷ | u |


Các thách thức

Nhiệm vụ của bạn là viết một chương trình hoặc hàm, đưa ra một danh sách các số nguyên đã ký không trống, diễn giải nó như một vectơ và chuẩn hóa nó. Điều này sẽ hoạt động cho bất kỳ số lượng kích thước nào, ví dụ (trường hợp kiểm tra được làm tròn đến hai chữ số thập phân):

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

Quy tắc:

  • Bạn có thể giả sử danh sách đầu vào sẽ:
    • Có ít nhất một yếu tố khác không
    • Chỉ chứa các số trong phạm vi dấu phẩy động tiêu chuẩn của ngôn ngữ của bạn
  • Đầu ra của bạn phải chính xác đến ít nhất hai chữ số thập phân . Trả lại các phân số / giá trị biểu tượng "chính xác vô hạn" cũng được cho phép, nếu đây là cách ngôn ngữ của bạn lưu trữ dữ liệu bên trong.
  • Đệ trình phải là một chương trình đầy đủ thực hiện I / O hoặc một chức năng. Các chức năng đệ trình có thể trả về một danh sách mới hoặc sửa đổi danh sách đã cho.
  • Các hàm / lớp dựng sẵn được cho phép. Ngoài ra, nếu ngôn ngữ của bạn có loại vectơ hỗ trợ số lượng kích thước tùy ý, bạn có thể lấy một trong các thứ nguyên này làm đầu vào.

Đây là một cuộc thi , vì vậy bạn nên đặt mục tiêu đạt được giải pháp ngắn nhất có thể (tính bằng byte).


Có phải có ít nhất hai vị trí thập phân cho mỗi đầu vào có thể (không thể áp dụng cho bất kỳ loại giá trị dấu phẩy động tiêu chuẩn nào) hoặc chỉ cho các ví dụ bạn cung cấp? Ví dụ: câu trả lời của Steadybox cung cấp 2 vị trí chính xác thập phân cho tất cả bài kiểm tra của bạn nhưng anh ta sử dụng số nguyên cho tổng bình phương mà tất nhiên không thành công cho hầu hết tất cả các đầu vào (ví dụ: [0,1, 0,1]).
Christoph

... bây giờ chúng ta chỉ chờ một lang có chức năng định mức tích hợp được ánh xạ tới một char ...
vaxquis

Phải có ít nhất 2dp cho mỗi đầu vào có thể
@Christoph

@FlipTack nhưng về cơ bản loại trừ tất cả các ngôn ngữ vì các điểm nổi có số mũ lớn hơn so với mantissa, điều đó có nghĩa là chúng không luôn có đủ độ chính xác để có bất kỳ vị trí thập phân nào.
Christoph

Tại sao số 6 trong ví dụ thứ 4 và -6 trong số 5 tương ứng bình thường hóa thành 1 và -1?
Cột

Câu trả lời:


15

05AB1E , 4 byte

Mã số:

nOt/

Hãy thử trực tuyến!

Giải trình

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
n0t những gì tôi mong đợi /
YSC

10

JavaScript (ES6), 31 byte

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

Các trường hợp thử nghiệm



9

J , 8 byte

%+/&.:*:

Hãy thử trực tuyến!

6 byte %|@j./hoạt động nếu vectơ ít nhất là 2 chiều .


Yêu cách nhận được sự vĩ đại.
cole

1
@cole dài hơn 1 byte:%1%:@#.*:
FrownyFrog

6
Bạn có thể vui lòng thêm một lời giải thích cho người không quen thuộc trong J?
MechMK1

% (chia cho) + / (tổng) &.: (dưới) *: (vuông). + tổng hai điều. + / tổng hợp một danh sách các thứ. &.: sửa đổi thao tác trước bằng cách áp dụng thao tác sau trước và nghịch đảo sau. % thường lấy hai đối số, nhưng (% f) là hàm từ x đến x% (fx). Hầu hết các nhà khai thác tự động làm việc trên danh sách.
Roman Odaisky

Và theo cùng một nguyên tắc, hàm mà Bình thường hóa một vectơ bằng cách thêm một số như vậy vào mỗi thành phần mà chúng tổng bằng 0 là Số - + / / # #.
Roman Odaisky



6

C,  73  70 byte

Cảm ơn @Christoph đã lưu một byte!

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

Hãy thử trực tuyến!


+1. s=0,i=0thay vì s=i=0lưu một
xanoetux

Tôi thích việc sử dụng s[-i]nhưng đáng buồn *--v/=sqrt(s);là ngắn hơn 1 byte.
Christoph

1
@xanoetux Cảm ơn, nhưng tôi cần khởi tạo các biến bên trong hàm, bởi vì các hàm cần phải được sử dụng lại . Ngoài ra, là biến toàn cục siđược tự động khởi tạo thành 0. (Hóa ra tôi không cần khởi tạo ihàm, vì hàm luôn để nó ở giá trị 0)
Steadybox

1
@Christoph Cảm ơn! Ban đầu tôi đã in các giá trị từ hàm, vì vậy tôi cần v[-i]lấy các giá trị theo đúng thứ tự.
Steadybox



3

CJam , 9 byte

{_:mhzf/}

Hãy thử trực tuyến!

Giải trình

_    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

Chạy với {1,2,3}:prgmNAME, {1,2,3}vectơ được chuẩn hóa.

Chia mỗi phần tử trong vectơ bằng căn bậc hai của tổng bình phương của các phần tử của nó.


Chúng tôi đã có câu trả lời tương tự!
kamoroso94

@ kamoroso94 Rất tiếc! Không thấy bạn khi tôi đăng bài này. Nếu bạn muốn thêm lời giải thích từ câu trả lời này vào câu trả lời của bạn, tôi sẽ xóa nó.
pizzapants184

Nah tôi sẽ loại bỏ của tôi. Bạn đặt nhiều nỗ lực hơn vào câu trả lời của mình: P
kamoroso94

3

R , 23 byte

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

Hãy thử trực tuyến!

v%*%vtính sản phẩm chấm của v với chính nó.
Hàm sẽ đưa ra cảnh báo cho các vectơ có độ dài 2 hoặc lớn hơn.



2

MATL , 5 byte

t2&|/

Hãy thử trực tuyến!

Tôi không hoàn toàn chắc chắn đây là cách ngắn nhất để làm điều này. Đầu tiên, chúng tôi nhân đôi đầu vào, sau đó chọn loại đầu ra thứ hai là |(hoặc là abs, normhoặc determinant). Cuối cùng, chúng tôi chia đầu vào theo định mức.

Thay thế cho 7 byte:

t2^sX^/




2

C ++ (gcc), 70 byte

Nhập bởi std::valarray<float>. Ghi đè lên vector ban đầu.

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

Hãy thử trực tuyến!


Tôi chỉ ẩn giấu codegolf mọi lúc, nhưng đây không phải là C ++ không hợp lệ, được đưa ra "#import", đây là một phần mở rộng cụ thể của Microsoft?
phresnel

@phresnel cũng #importhoạt động ít nhất với GCC, Clang và MinGW. Nhưng, vâng, nó không phải là C ++ tiêu chuẩn.
Steadybox

@phresnel Tôi quên chỉ định gcc. Đã sửa.
Colera Su


2

APL (Dyalog) , 13 12 10 byte

Lưu 1 byte nhờ @ Adám

2 byte được lưu nhờ @ngn

⊢÷.5*⍨+.×⍨

Hãy thử trực tuyến!

Làm sao?

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

Đào tạo ít hơn:⊢÷.5*⍨(+/×⍨)
Adám

@ Adám cảm ơn rất nhiều! Tôi đã cố gắng trong nhiều giờ, không thể có bất kỳ chuyến tàu nào để làm việc
Uriel

Chúng ta nên làm một cái gì đó về điều đó, vì nó thực sự không quá khó. Khi bạn có một hàm đơn âm (khác với hàm ngoài cùng bên phải), hãy bắt đầu dấu ngoặc đơn ở bên trái (hoặc sử dụng hàm nếu nó không xuất phát). Ngoài ra, chỉ cần trao đổi cho : {⍵÷.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()))

Hãy thử trực tuyến!

+64 byte cho 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;}

Hãy thử trực tuyến!

+13 byte cho using System;

Cách tiếp cận phi Linq

Khói

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 mã, +1 cho -pcờ.

g/RT$+g*g

Lấy vectơ làm đối số dòng lệnh riêng biệt. Hãy thử trực tuyến!

Làm thế nào nó hoạt động

      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

Bình thường, 5 byte

cR.aQ

Dùng thử trực tuyến: Test Suite

Giải trình:

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 $_»²}

Hãy thử trực tuyến!

$_, đối số danh sách cho hàm, được chia theo phần tử ( »/») cho căn bậc hai của tổng bình phương của các phần tử ( »²).


1

Ruby, 39 35 byte

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

-4 byte nhờ G B.


1
Lưu một số byte bằng cách sử dụng sum{...}thay vìmap{...}.sum
GB

0

APL NARS 12 ký tự

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

Bạn không phải tính số f← byte của mình, vì bạn có thể sử dụng các dfns mà không cần nó. Nhân tiện, một byte đơn trong NARS? Tôi không quen thuộc với nó, vì vậy chỉ cần hỏi
Uriel

@Uriel Nars Apl trong số ít tôi biết sẽ viết bằng Unicode nên số byte nên là 12x2
RosLuP

0

Google Sheets, 65 byte

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

Danh sách đầu vào nằm trong cột Avới một mục nhập trên mỗi ô. Đây là cách bảng tính thường sử dụng danh sách. Thật không may, điều này thường sẽ dẫn đến một danh sách dài ,0,0,0,0,0,....ở cuối, vì vậy chúng tôi phải bỏ qua những người cóIf Blank then Blank else Math logic.

Nếu đó là tất cả trong một ô, thay vào đó, giải pháp sẽ là 95 byte:

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

0

Swift 4, 44 byte

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

Tính toán lại định mức vectơ cho mọi thành phần, nhưng ít nhất nó thật ngắn gọn!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.