ทำเวกเตอร์ให้เป็นมาตรฐาน


28

การทำเวกเตอร์ให้เป็นมาตรฐานคือการปรับสเกลให้มีความยาว 1 ( เวกเตอร์หน่วย ) ในขณะที่ทำให้ทิศทางสอดคล้อง

ตัวอย่างเช่นถ้าเราต้องการทำให้เวกเตอร์เป็นมาตรฐานด้วย 3 องค์ประกอบคุณจะพบความยาวก่อน:

| ยู | = 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]

กฎ:

  • คุณสามารถสันนิษฐานว่ารายการอินพุตจะ:
    • มีองค์ประกอบที่ไม่เป็นศูนย์อย่างน้อยหนึ่งรายการ
    • มีตัวเลขอยู่ในช่วงจุดลอยตัวมาตรฐานของภาษาของคุณ
  • การส่งออกของคุณควรจะถูกต้องอย่างน้อย ทศนิยมสองตำแหน่ง อนุญาตให้มีการคืนค่าเศษส่วน / สัญลักษณ์ "ความแม่นยำไม่สิ้นสุด" หากนี่คือวิธีที่ภาษาของคุณจัดเก็บข้อมูลภายใน
  • การส่งควรเป็นโปรแกรมเต็มรูปแบบซึ่งดำเนินการ I / O หรือฟังก์ชั่น การส่งฟังก์ชั่นสามารถส่งคืนรายการใหม่หรือแก้ไขรายการที่กำหนด
  • อนุญาตให้ใช้ฟังก์ชัน / คลาสเวกเตอร์ในตัว นอกจากนี้หากภาษาของคุณมีประเภทเวกเตอร์ที่รองรับจำนวนมิติโดยพลการคุณสามารถใช้หนึ่งในสิ่งเหล่านี้เป็นอินพุต

นี่เป็นการแข่งขันดังนั้นคุณควรตั้งเป้าหมายที่จะแก้ปัญหาให้สั้นที่สุดเท่าที่จะทำได้ (เป็นไบต์)


จำเป็นต้องมีตำแหน่งทศนิยมอย่างน้อยสองตำแหน่งสำหรับทุกอินพุตที่เป็นไปได้ (ซึ่งเป็นไปไม่ได้สำหรับประเภทจุดลอยตัวมาตรฐานใด ๆ ) หรือสำหรับตัวอย่างที่คุณให้เท่านั้น เช่นคำตอบของ Steadybox ให้ความแม่นยำทศนิยม 2 ตำแหน่งสำหรับการทดสอบทั้งหมดของคุณ แต่เขาใช้ ints เพื่อหาผลรวมของกำลังสองซึ่งแน่นอนว่าล้มเหลวสำหรับอินพุตเกือบทั้งหมด (เช่น [0.1, 0.1])
Christoph

... ตอนนี้เราก็รอให้ lang ที่มีในตัวฟังก์ชั่นบรรทัดฐานจับคู่กับหนึ่งถ่าน ...
vaxquis

ควรมีอย่างน้อย 2dp สำหรับทุกอินพุตที่เป็นไปได้
@Christoph

@FlipTack แต่มีกฎว่าโดยทั่วไปทุกภาษาเนื่องจากคะแนนทศนิยมมีเลขชี้กำลังใหญ่กว่า mantissa ซึ่งหมายความว่าพวกเขาไม่มีความแม่นยำเพียงพอที่จะมีทศนิยม
Christoph

เหตุใดจึงไม่ 6 ในตัวอย่างที่ 4 และ -6 ในลำดับที่ 5 ตามปกติให้เป็น 1 และ -1
เสา

คำตอบ:



10

JavaScript (ES6), 31 ไบต์

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

กรณีทดสอบ



9

ชอบวิธีการรับขนาด
โคล

1
@cole อีก 1 ไบต์อีกต่อไป:%1%:@#.*:
FrownyFrog

6
คุณช่วยเพิ่มคำอธิบายสำหรับผู้ที่ไม่ได้ฝึกหัดใน J ได้ไหม
MechMK1

% (หารด้วย) + / (ผลรวม) &: (ใต้) *: (สี่เหลี่ยม) + สรุปสองสิ่ง + / สรุปรายการสิ่งต่าง ๆ & .: แก้ไขการดำเนินการก่อนหน้านี้โดยใช้การดำเนินการต่อไปนี้ก่อนและผกผันในภายหลัง % โดยปกติจะรับสองอาร์กิวเมนต์ แต่ (% f) เป็นฟังก์ชันจาก x ถึง x% (fx) ผู้ประกอบการส่วนใหญ่ทำงานในรายการโดยอัตโนมัติ
Roman Odaisky

และด้วยหลักการเดียวกันฟังก์ชั่นที่ "ทำให้ปกติ" เวกเตอร์โดยการเพิ่มจำนวนดังกล่าวให้กับแต่ละองค์ประกอบที่พวกเขารวมเป็นศูนย์คือ“ - + /% #”
Roman Odaisky

8

เยลลี่ , 5 3 ไบต์

÷ÆḊ

ลองออนไลน์! หรือดูชุดทดสอบ

บันทึก 2 ไบต์ด้วยไมล์!


3 ไบต์ด้วย÷ÆḊ
ไมล์

@miles Huh ไม่เคยรู้เรื่องตัวนี้เลย ขอบคุณ
caird coinheringaahing

โชคไม่ดีที่ built-in ให้ + ve mod สำหรับ scalars ต่อ TIO ค่าสัมบูรณ์แน่นอน .. ปัญหาที่ขอรักษาเครื่องหมาย
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จะเริ่มต้นโดยอัตโนมัติเป็น 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-Basic, 6 ไบต์

Ans/√(sum(Ans2

ทำงานกับ{1,2,3}:prgmNAMEที่{1,2,3}เป็นเวกเตอร์ที่จะปกติ

หารแต่ละองค์ประกอบในเวกเตอร์ด้วยสแควร์รูทของผลรวมของกำลังสองขององค์ประกอบ


เราได้คำตอบเดียวกัน!
kamoroso94

@ kamoroso94 อ๊ะ! ไม่เห็นคุณเมื่อฉันโพสต์สิ่งนี้ หากคุณต้องการเพิ่มคำอธิบายจากคำตอบของคุณฉันจะลบสิ่งนี้
pizzapants184

ไม่ฉันจะเอาของฉันออก คุณใช้ความพยายามมากขึ้นในคำตอบของคุณ: P
kamoroso94



2

MATL , 5 ไบต์

t2&|/

ลองออนไลน์!

ฉันไม่แน่ใจว่านี่เป็นวิธีที่สั้นที่สุดในการทำเช่นนี้ ครั้งแรกที่เราทำซ้ำการป้อนข้อมูลแล้วเลือกประเภทเอาท์พุทที่สองของ|(ซึ่งเป็นทั้งabs, normหรือdeterminant) ในที่สุดเราก็แบ่งข้อมูลตามบรรทัดฐาน

ทางเลือกสำหรับ 7 ไบต์:

t2^sX^/




2

C ++ (gcc), 70 ไบต์

std::valarray<float>การป้อนข้อมูลโดย เขียนทับเวกเตอร์ดั้งเดิม

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

ลองออนไลน์!


ฉันเพิ่งซุ่มซ่อน codegolf ทุกครั้ง แต่ C ++ นี้ไม่ถูกต้องที่กำหนด "#import" ซึ่งเป็นส่วนขยายเฉพาะของ Microsoft
phresnel

@phresnel #importทำงานอย่างน้อยกับ GCC, Clang และ MinGW เช่นกัน แต่ใช่มันไม่ใช่มาตรฐาน C ++
Steadybox

@phresnel ฉันลืมระบุ gcc คงที่
Colera Su


2

APL (Dyalog) , 13 12 10 ไบต์

บันทึก 1 ไบต์ด้วย @ Adám

บันทึก 2 ไบต์ด้วย @ngn

⊢÷.5*⍨+.×⍨

ลองออนไลน์!

อย่างไร?

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

ฝึกให้น้อยลง:⊢÷.5*⍨(+/×⍨)
Adám

@ Adámขอบคุณมาก! ฉันได้พยายามชั่วโมงไม่สามารถรับรถไฟใด ๆ ในการทำงาน
ยูเรียล

เราควรทำอะไรสักอย่างเกี่ยวกับเรื่องนี้เพราะมันไม่ยากจริงๆ เมื่อคุณมีฟังก์ชั่น monadic (นอกเหนือจากที่อยู่ทางขวาสุด) ให้เริ่มวงเล็บไว้ทางซ้าย (หรือใช้ a หากไม่ได้รับมา) อื่น ๆ กว่าที่เป็นเพียงแค่การแลกเปลี่ยนและสำหรับและ: {⍵÷.5*⍨+/×⍨⍵}→การ{⍵÷.5*⍨(+/(×⍨⍵))}→การ⊢÷.5*⍨(+/(×⍨⊢))→การ⊢÷.5*⍨(+/(×⍨))→การ⊢÷.5*⍨(+/×⍨)
อดัม

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


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

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 ไบต์

รหัส 9 ไบต์ +1 สำหรับการ-pตั้งค่าสถานะ

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

Perl 6 , 25 ไบต์

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

ลองออนไลน์!

$_อาร์กิวเมนต์ list ของฟังก์ชันแบ่งเป็น elementwise ( »/») โดยสแควร์รูทของผลรวมของกำลังสองขององค์ประกอบ ( »²)


1

Ruby, 39 35 ไบต์

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

-4 ไบต์ขอบคุณ G B.


1
บันทึกไบต์โดยใช้sum{...}แทนmap{...}.sum
GB

0

APL NARS 12 ตัวละคร

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

คุณไม่จำเป็นต้องนับจำนวนf← ไบต์เนื่องจากคุณสามารถใช้ dfns หากไม่มี ยังไงก็ตามไบต์เดียวใน NARS คืออะไร? ฉันไม่คุ้นเคยกับมันดังนั้นเพียงแค่ถาม
Uriel

@Uriel Nars Apl ในไม่กี่ที่ฉันรู้ว่าจะเขียนด้วย Unicode ดังนั้นจำนวนไบต์ควรเป็น 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

Swift 4, 44 bytes

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

คำนวณ vector norm ใหม่สำหรับทุกองค์ประกอบ แต่อย่างน้อยมันก็เป็นคำย่อ!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.