Vandermonde ตัวกำหนด


25

ให้เวกเตอร์ของnค่า(x1,x2,x3,...,xn)ส่งคืนดีเทอร์มิแนนต์ของเมทริกซ์ Vandermonde ที่เกี่ยวข้อง

ดีเทอร์มิแนนต์นี้สามารถเขียนเป็น:

สูตร

รายละเอียด

โปรแกรม / ฟังก์ชั่นของคุณต้องยอมรับรายการหมายเลขจุดลอยตัวในรูปแบบที่สะดวกใด ๆ ที่อนุญาตให้มีความยาวผันแปรและส่งออกปัจจัยที่กำหนด

คุณสามารถสมมติว่าอินพุตรวมทั้งเอาต์พุตอยู่ในช่วงของค่าที่ภาษาของคุณรองรับ หากภาษาของคุณไม่รองรับหมายเลขทศนิยมคุณอาจถือว่าเป็นจำนวนเต็ม

บางกรณีทดสอบ

โปรดทราบว่าเมื่อใดก็ตามที่มีสองรายการเท่ากันดีเทอร์มิแนนต์จะเป็น0เนื่องจากมีสองแถวเท่ากันในเมทริกซ์ Vandermonde ที่เกี่ยวข้อง ขอบคุณ @randomra สำหรับการชี้ให้เห็น testcase ที่ขาดหายไปนี้

[1,2,2,3]            0 
[-13513]             1
[1,2]                1
[2,1]               -1
[1,2,3]              2
[3,2,1]             -2
[1,2,3,4]           12
[1,2,3,4,5]        288
[1,2,4]              6
[1,2,4,8]         1008
[1,2,4,8,16]  20321280
[0, .1, .2,...,1]   6.6586e-028
[1, .5, .25, .125]  0.00384521
[.25, .5, 1, 2, 4]  19.3798828

เราสามารถสมมติว่าอินพุตมีความยาวอย่างน้อย 2 ได้หรือไม่
PurkkaKoodari

@ Pietu1998 ไม่ดูกรณีทดสอบครั้งแรก
Alex A.

3
คดีสำคัญการทดสอบ: [1,2,2,3] => 0: สององค์ประกอบที่เท่าเทียมกันในอาร์เรย์เพื่อทดสอบว่าการตรวจสอบรหัสตัวเองที่แตกต่างกัน ( xi-xi) 0โดยเปรียบเทียบกับ
randomra

@ randomra ขอบคุณฉันลืมที่จะรวมหนึ่งในนั้น เมื่อใดก็ตามที่สองรายการมีค่าเท่ากันดีเทอร์มิแนนต์จะเป็น 0 เนื่องจากมีสองครั้งในแถวเดียวกัน
ข้อบกพร่อง

1
@flawr ผลลัพธ์ที่คาดหวังนั้นชัดเจนจากข้อกำหนดของคุณ ฉันแนะนำกรณีทดสอบดังนั้นคำตอบที่ไม่ได้เตรียมไว้สำหรับตัวเลขที่เท่ากันสามารถหาข้อผิดพลาดได้ง่ายขึ้น
Randomra

คำตอบ:


9

เยลลี่ 6 ไบต์

œc2IFP

œc2รับชุดค่าผสมทั้งหมดโดยไม่ต้องเปลี่ยนความยาว 2. Iคำนวณรายการผลต่างของคู่เหล่านั้นโดยให้รายการเหมือน[[1], [2], [3], ..., [1]]กัน เราFlatten และใช้Product

ลองที่นี่!


8

Ruby, 49 47 ไบต์

->x{eval(x.combination(2).map{|a,b|b-a}*?*)||1}

นี่คือฟังก์ชั่นแลมบ์ดาที่ยอมรับอาร์เรย์มูลค่าหนึ่งมิติที่แท้จริงและส่งกลับค่าทศนิยมหรือจำนวนเต็มขึ้นอยู่กับชนิดของอินพุต f.call(input)เรียกว่ากำหนดให้ตัวแปรแล้วทำ

เราได้รับรวมกันทั้งหมด 2 ขนาดใช้และได้รับความแตกต่างของแต่ละคู่ใช้.combination(2) .map {|a, b| b - a}เราเข้าร่วมอาร์เรย์ผลลัพธ์เป็นสตริงคั่นด้วย*แล้วevalนี่ซึ่งส่งคืนผลิตภัณฑ์ หากอินพุตมีความยาว 1 จะเป็นnilเช่นนี้ซึ่งเป็นเท็จในทับทิมดังนั้นเราสามารถ||1สิ้นสุดที่จะคืนค่า 1 ในสถานการณ์นี้ โปรดทราบว่านี่ยังใช้งานได้เมื่อผลิตภัณฑ์เป็น 0 เพราะเหตุผลใดก็ตาม 0 คือความจริงในทับทิม

ตรวจสอบกรณีทดสอบทั้งหมดออนไลน์

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


7

Mathematica ขนาด 30 ไบต์

1##&@@(#2-#&@@@#~Subsets~{2})&

นี่คือฟังก์ชั่นที่ไม่ระบุชื่อ

ขยายตัว Mathematica (1 ##1 & ) @@ Apply[#2 - #1 & , Subsets[#1, {2}], {1}] &ก็จะเทียบเท่ากับ 1##&เป็นเทียบเท่าTimes(เคล็ดลับขอบคุณหน้า) Subsets[list, {2}]ซึ่งจะนำไปใช้กับแต่ละคู่ที่แตกต่างกันขององค์ประกอบจากรายการการป้อนข้อมูลที่สร้างขึ้นโดย โปรดทราบว่าSubsetsจะไม่ตรวจสอบความเป็นเอกลักษณ์ขององค์ประกอบ


5

J, 13 ไบต์

-/ .*@(^/i.)#

นี่คือฟังก์ชัน monadic ที่ใช้ในอาร์เรย์และส่งคืนตัวเลข ใช้มันแบบนี้:

  f =: -/ .*@(^/i.)#
  f 1 2 4
6

คำอธิบาย

ฉันสร้างเมทริกซ์ Vandermonde ที่เกี่ยวข้องกับอาร์เรย์อินพุตอย่างชัดเจนแล้วคำนวณดีเทอร์มิแนนต์

-/ .*@(^/i.)#   Denote input by y
            #   Length of y, say n
         i.     Range from 0 to n - 1
       ^/       Direct product of y with the above range using ^ (power)
                This gives the Vandermonde matrix
                 1 y0     y0^2     ... y0^(n-1)
                 1 y1     y1^2     ... y1^(n-1)
                   ...
                 1 y(n-1) y(n-1)^2 ... y(n-1)^(n-1)
-/ .*           Evaluate the determinant of this matrix

ผมคิดว่าช่องว่างก็ไม่ใช่สิ่งสำคัญในการเจ ...
Conor โอไบรอัน

@ CᴏɴᴏʀO'Bʀɪᴇɴดีเทอร์มิแนนต์เป็นกรณีพิเศษที่ต้องใช้พื้นที่แยกเนื่องจาก.เป็นอักขระตัวแก้ไข เหมือนกันสำหรับ:ตัวมันเอง
Zgarb

Oh! มันเท่ห์มาก
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴที่จริงแล้วฉันคิดว่านั่นเป็นสิ่งที่ทำให้ J uncool J ย่อมาจาก Jot คือจุดหรือวงแหวนเล็ก ๆ (APL's ) ในขณะที่jotting กับ J ... การโอเวอร์โหลดอย่างไม่น่าเชื่อ.และ:(ซึ่งเป็นภาพเดียวกันกับที่ซ้อนกันสองครั้ง.) ทำให้ J อ่านยาก (สำหรับฉัน) จะยิ่งมีมากขึ้นเมื่อช่องว่างที่อยู่ถัดจากจุดกำหนดความหมาย! เจ.จะต้องเป็นสัญลักษณ์มากเกินไปมากที่สุดในประวัติศาสตร์ของการคำนวณ: ฉันนับ 53 ความหมายที่แตกต่างของ.และ 43 (61 ถ้าคุณนับทั้งหมด_9:ไป9:) :ความหมายที่แตกต่างของ Yukk ;-)
อดัม

@ Nᴮᶻมันอาจช่วยให้คิด เป็นโทเค็นของตัวเอง; ดังนั้นจึงสามารถทำได้โดยไม่ต้องเว้นวรรคสีขาวสำหรับผู้ปฏิบัติงานรายอื่น อย่างไรก็ตามถ้า J ไม่เหมาะสำหรับคุณนั่นก็เป็นที่เข้าใจได้
Conor O'Brien

4

MATL , 9

!G-qZRQpp

ลองออนไลน์!

สิ่งนี้คำนวณเมทริกซ์ของความแตกต่างทั้งหมดแล้วเก็บเฉพาะส่วนใต้เส้นทแยงมุมหลักเท่านั้นสร้างรายการอื่น ๆ1เพื่อไม่ให้กระทบกับผลิตภัณฑ์ ฟังก์ชั่นรูปสามเหลี่ยมที่ลดลงทำให้องค์ประกอบที่ไม่พึงประสงค์ไม่0 1เราก็ลบ1, เอาส่วนสามเหลี่ยมที่ต่ำกว่า, แล้วบวก1กลับ จากนั้นเราสามารถนำผลิตภัณฑ์ของทุกรายการ

t     % take input. Transpose
G     % push input again
-     % subtract with broadccast: matrix of all pairwise differences
q     % subtract 1
ZR    % make zero all values on the diagonal and above
Q     % add 1
p     % product of all columns
p     % product of all those products

มันโชคร้าย แต่2Xn!dpดูเหมือนว่าจะทำงานกับค่าเดียวเมื่อค่ามากกว่าหรือเท่ากับ 2 ... ฉันได้เขียนมันเองที่พยายามเอาชนะ Jelly: P
FryAmTheEggman

@FryAmTheEggman Awww คุณพูดถูก ขอบคุณสำหรับหัวขึ้น!
Luis Mendo

ใช่ฉันคิดว่านั่นเป็นปัญหา ฉันจะลองทำอะไรซักอย่างเช่นการเพิ่มเสื้อคลุมเมื่อคุณได้Xnทำเช็คif size(arg) == [1,1] ...หรืออะไรซักอย่าง ฉันขี้เกียจเกินไปที่จะดูแหล่งที่มา แต่ (หวังว่า) มันไม่ควรจะยากขนาดนั้น
FryAmTheEggman

@FryAmTheEggman อันที่จริงฉันไม่แน่ใจว่าเป็นปัญหา (นั่นเป็นเหตุผลที่ฉันแก้ไขความคิดเห็นของฉันได้อย่างรวดเร็ว) หากอินพุตแรกเป็นตัวเลขดังนั้นอินพุตที่สองควรเป็น1หรือ0จากนั้นจะไม่มีความแตกต่างหากอินพุตแรกถูกตีความว่าเป็นอาร์เรย์หรือเป็นตัวเลข ปัญหาที่แท้จริงคืออินพุตที่สองต้องไม่เกินขนาดอาร์เรย์ "มีกี่วิธีในการเลือก 2 องค์ประกอบจาก 1 องค์ประกอบ" ในกรณีนี้แตกต่างอาร์เรย์ / จำนวนเรื่อง: ถ้าใส่แรกคือผลตอบแทนอาร์เรย์[](อาร์เรย์ว่างเปล่า) 0ถ้ามันมีผลตอบแทนจำนวน ฉันเดาว่าฉันจะกลับ[]เพราะpบังคับให้มีการตีความอื่น ๆ
Luis Mendo

@FryAmTheEggman ฉันคิดว่าฉันจะแยกฟังก์ชั่นออกเป็นสองรุ่น ขอบคุณอีกครั้ง!
Luis Mendo

3

Pyth, 15 13 12 11 ไบต์

*F+1-M.c_Q2
         Q    take input (in format [1,2,3,...])
        _     reverse the array: later we will be subtracting, and we want to
                subtract earlier elements from later elements
      .c  2   combinations of length 2: this gets the correct pairs
    -M        map a[0] - a[1] over each subarray
  +1          prepend a 1 to the array: this does not change the following
                result, but prevents an error on empty array
*F            fold over multiply (multiply all numbers in array)

ขอบคุณ@FryAmTheEggmanและ@ Pietu1998สำหรับแต่ละไบต์!


1
* F ในอาเรย์ที่ว่างเปล่าควรเป็น 1
lirtosiast

3

Mathematica ขนาด 32 ไบต์

Det@Table[#^j,{j,0,Length@#-1}]&

ฉันรู้สึกประหลาดใจที่ไม่พบสิ่งที่สร้างขึ้นสำหรับ Vandermonde อาจเป็นเพราะมันง่ายที่จะทำเอง

อันนี้เป็นการสร้างทรานสคริปท์ของ VM อย่างชัดเจนและใช้ดีเทอร์มิแนนต์ (ซึ่งแน่นอนเหมือนกับของดั้งเดิม) วิธีนี้กลายเป็นสั้นกว่าการใช้สูตรใด ๆ ที่ฉันรู้


3

Haskell, 34 ไบต์

f(h:t)=f t*product[x-h|x<-t]
f _=1

โซลูชันแบบเรียกซ้ำ เมื่อองค์ประกอบใหม่hถูกนำไปรวมไว้ที่ด้านหน้านิพจน์จะถูกคูณด้วยผลคูณของx-hสำหรับแต่ละองค์ประกอบxของรายการ ขอบคุณ Zgarb สำหรับ 1 ไบต์


2

Matlab, 26 ไบต์

(noncompeting)

การใช้บิวอินอย่างตรงไปตรงมา โปรดทราบว่า (อีกครั้ง) Matlab vanderสร้างการฝึกอบรม Vandermonde แต่ด้วยลำดับของแถวที่พลิก

@(v)det(fliplr(vander(v)))

2
ทำไมไม่ใช่การแข่งขัน
Alex A.

3
เนื่องจากฉันเป็นผู้สร้างความท้าทายนี้ฉันแค่ต้องการให้สิ่งนี้เพื่อให้ผู้คนสามารถลองตัวอย่างของพวกเขาเอง
ข้อบกพร่อง

Det ไม่ใช่ (พลิกแถว) = (-1) ^ n Det (ดั้งเดิม) หรือไม่
hYPotenuser

ฉันไม่แน่ใจเหมือนกันเพราะสวิตช์ดีเทอร์มิแนนต์จะลงชื่อเมื่อใดก็ตามที่คุณสลับสองคอลัมน์หรือแถว
ข้อบกพร่อง

@hYPotenuser - แทนที่ n ด้วย n + 1 สิ่งที่คุณทำคือการคูณด้วยเมทริกซ์ P ซึ่งเป็นศูนย์ทั้งหมดยกเว้นเส้นทแยงมุมไปจากด้านล่างซ้ายไปขวาบน (คุณต้องการเดช (P * vander (v)) = เดช (P) เด (vander (v) ))) เมื่อขยายตามคอลัมน์แรกหรืออะไรก็ตามคุณจะเห็น det (P) = (-1) ^ (n + 1)
แบทแมน

2

สนิม 86 ไบต์

|a:Vec<f32>|(0..a.len()).flat_map(|x|(x+1..a.len()).map(move|y|y-x)).fold(1,|a,b|a*b);

สนิม verbose ตามปกติ ...

คำอธิบายจะมาในภายหลัง (แต่ค่อนข้างตรงไปตรงมา)


2

Perl, 38 41ไบต์

รวม +1 สำหรับ -p

ให้ตัวเลขในบรรทัดที่ STDIN ดังนั้นเช่นทำงานเป็น

perl -p vandermonde.pl <<< "1 2 4 8"

ใช้ regex ชั่วร้ายเพื่อให้ได้ลูปสองครั้ง:

vandermonde.pl:

$n=1;/(^| ).* (??{$n*=$'-$&;A})/;*_=n

2

JavaScript (ES6), 61 ไบต์

a=>a.reduce((p,x,i)=>a.slice(0,i).reduce((p,y)=>p*(x-y),p),1)

ฉันลองใช้อาร์เรย์ความเข้าใจ (Firefox 30-57) และนานกว่า 5 ไบต์:

a=>[for(i of a.keys(p=1))for(j of Array(i).keys())p*=a[i]-a[j]]&&p

วงซ้อนซ้อนที่น่าเบื่อนั้นสั้นกว่า


1

Haskell, 53 ไบต์

 f x=product[x!!j-x!!i|j<-[1..length x-1],i<-[0..j-1]]

ตัวอย่างการใช้งาน: ->f [1,2,4,8,16]20321280

ผ่านดัชนีjและiในวงที่ซ้อนกันและทำรายการของความแตกต่างขององค์ประกอบที่ตำแหน่งที่และj iสร้างผลิตภัณฑ์ขององค์ประกอบทั้งหมดในรายการ

ตัวแปรอื่น ๆ ที่กลายเป็นอีกต่อไปเล็กน้อย:

f x=product[last l-i|l<-scanl1(++)$pure<$>x,i<-init l], 54 ไบต์

import Data.List;f i=product[y-x|[x,y]<-subsequences i], 55 ไบต์


1

CJam, 16 ไบต์

1l~{)1$f-@+:*\}h

เพื่อตอบสนองต่อการโพสต์ของ A Simmonsแม้ว่า CJam จะขาดผู้ประกอบการรวมกัน แต่ก็เป็นไปได้ที่จะทำได้ดีกว่า :)

-1 ไบต์ขอบคุณ @ MartinBüttner

ลองใช้ออนไลน์ | ชุดทดสอบ

1                   Push 1 to kick off product
 l~                 Read and evaluate input V
   {          }h    Do-while loop until V is empty
    )                 Pop last element of V
     1$               Copy the prefix
       f-             Element-wise subtract each from the popped element
         @+           Add the current product to the resulting array
           :*         Take product to produce new product
             \        Swap, putting V back on top

0

CJam, 32 ไบต์

1q~La\{1$f++}/{,2=},{~-}%~]La-:*

ฉันแน่ใจว่าใครบางคนสามารถเล่นกอล์ฟได้ดีขึ้นใน CJam ... ปัญหาหลักคือฉันไม่เห็นวิธีที่ดีในการรับเซตย่อยเพื่อที่จะได้ใช้ไบต์ส่วนใหญ่ของฉันหมด สิ่งนี้สร้างชุดพลังงาน (ใช้ความคิดโดย Martin Büttner) จากนั้นเลือกองค์ประกอบความยาว 2



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