Vandermonde Belirleyici


25

Verilen bir ndeğerler vektörü (x1,x2,x3,...,xn)karşılık gelen Vandermonde matrisinin determinantını döndürür .

Bu belirleyici şöyle yazılabilir:

formül

ayrıntılar

Programınız / işlevin değişken uzunluk sağlayan herhangi bir uygun formatta kayan noktalı sayıların bir listesini kabul etmek ve belirtilen determinantı çıkarmak zorundadır.

Çıkışın yanı sıra girişin, dilinizin desteklediği değerler arasında olduğunu varsayabilirsiniz. Diliniz kayan nokta sayılarını desteklemiyorsa, tamsayılar olduğunu varsayabilirsiniz.

Bazı test durumları

İki eşit giriş olduğunda, determinantın 0ilgili Vandermonde matrisinde iki eşit sıra olduğu gibi olacağını unutmayın . Bu kayıp test çantasını işaret ettiği için @randomra'ya teşekkürler.

[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

Girişin en az 2 uzunlukta olduğunu varsayabilir miyiz?
PurkkaKoodari

@ Pietu1998 Hayır, ilk test olayına bakın.
Alex A.

3
Önemli sınama durumu:: [1,2,2,3] => 0Kodun kendi kendini farkını ( xi-xi) yalnızca karşılaştırarak denetleyip denetlemediğini sınamak için dizideki iki eşit öğe 0.
rastgele

@randomra Teşekkürler, bunlardan birini eklemeyi tamamen unuttum. İki giriş eşit olduğunda, determinant aynı satırın iki katı olduğu gibi 0 olacaktır.
kusur

1
@flawr Beklenen çıktı sizin özelliklerinden açıktı. Test vakasını önerdim, böylece eşit sayılara hazırlanamayan cevaplar hatalarını daha kolay bulabilirdi.
randomra

Yanıtlar:


9

Jöle, 6 bayt

œc2IFP

œc2uzunluğu değiştirilmeden tüm kombinasyonları alır 2. Ibu çiftlerin her birinin fark listesini hesaplar, şöyle bir liste oluşturur [[1], [2], [3], ..., [1]]. Biz Flatten ve almak PÜ.

Burada dene!


8

Ruby, 49 47 bayt

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

Bu, gerçek değerli, tek boyutlu bir diziyi kabul eden ve girişin türüne bağlı olarak bir şamandıra veya bir tam sayı döndüren bir lambda işlevidir. Aramak için değişkene atayın sonra yapın f.call(input).

Boyut 2'nin tüm kombinasyonlarını kullanarak .combination(2)ve her çift için farklılıkları kullandık .map {|a, b| b - a}. Sonuçta elde edilen diziyi *, bundan sonra eval, ürünü döndüren, bununla ayrılmış bir dizgeye birleştiririz . Girdi uzunluğu 1 nilise, Ruby'de falsey olan bu olacaktır , bu durumda ||1en sonunda 1'e geri dönebiliriz. Unutmayın ki, bu ürün 0 olduğunda hala işe yarıyor.

Tüm test durumlarını çevrimiçi olarak doğrulayın

Doorknob sayesinde 2 bayt kaydedildi!


7

Mathematica, 30 bayt

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

Bu anonim bir işlevdir.

Mathematica tarafından genişletilen, eşdeğerdir (1 ##1 & ) @@ Apply[#2 - #1 & , Subsets[#1, {2}], {1}] &. giriş listesindeki her bir farklı öğe çiftine uygulanan, 1##&eşdeğer Times(teşekkürler ipuçları sayfası) Subsets[list, {2}]. SubsetsElementlerin benzersizliğini kontrol etmediğini unutmayın .


5

J, 13 bayt

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

Bu bir dizi alır ve bir sayı döndüren bir monadik fonksiyondur. Bu şekilde kullanın:

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

açıklama

Giriş dizisi ile ilişkilendirilmiş Vandermonde matrisini açıkça yapıyorum ve ardından determinantını hesapladım.

-/ .*@(^/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

Boşlukların J için çok önemli olmadığını sanıyordum ...
Conor O'Brien,

@ CᴏɴᴏʀO'Bʀɪᴇɴ Belirleyici, ayırıcı boşluk gerektiren özel bir durumdur, çünkü .aynı zamanda bir değiştirici karakterdir. :Kendi başına aynı .
Zgarb

Ah! Çok havalı.
Conor O'Brien,

@ CᴏɴᴏʀO'Bʀɪᴇɴ Aslına bakarsanız, J'nin soğumasını tam olarak yapan şey bu. J, Jot, yani bir nokta veya küçük halka (APL'ler ) anlamına gelir, J ile not etme gibi ... İnanılmaz derecede aşırı yüklendi .ve :(yine görsel olarak iki istiflenmiş .s ile aynı ), J'nin okunmasını zorlaştırıyor (benim için). Ne kadar çok, noktaların yanındaki boşluklar anlam belirlediğinde! J adlı .bilgisayar tarihinin tümünde en fazla yüklenmiş sembolü olmalıdır: Ben 53 farklı anlamlarını saymak .(eğer tüm sayarsanız 61 ve 43 _9:için 9:ayrı anlamlar) :. Yukk. ;-)
Adám

@ Nᴮᶻ düşünmek için yardımcı olabilir. kendi belirteci olarak; bu nedenle, beyaz bir boşluk olmadan başka bir operatörle karıştırılabilir. Eğer J sizin için değilse, bu anlaşılabilir bir durumdur.
Conor O'Brien,

4

MATL , 9

!G-qZRQpp

Çevrimiçi deneyin!

Bu, tüm farklılıkların bir matrisini hesaplar ve sonra sadece ana köşegen altındaki kısmı tutar, diğer girdileri 1de ürünü etkilemeyecek şekilde yapar. Alt üçgen fonksiyonu istenmeyen unsurları yapar 0, değil 1. Bu yüzden çıkarırız 1, alt üçgen kısmını alırız ve 1geri ekleriz . Sonra tüm girişlerin ürününü alabiliriz.

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

Bu talihsiz ama 2Xn!dpdeğer büyükse veya 2'ye eşit olduğunda sadece ... kendim Jelly yenmek için çalışan yazmıştı tek değerlerle işe görünüyor: P
FryAmTheEggman

@FryAmTheEggman Awww. Haklısın. Heads-up için teşekkürler!
Luis Mendo

Evet, bunun sorun olduğunu anladım. XnBir çek if size(arg) == [1,1] ...ya da başka bir şey yapmayı planladığınızda sarıcı eklemek gibi bir şey denemeyi düşünürdüm . Kaynağa bakmak için çok tembelim ama (umarım) o kadar zor olmamalı.
FryAmTheEggman

@FryAmTheEggman Aslında sorunun bu olduğundan emin değilim (bu yüzden yorumumu hızlıca değiştirdim). İlk giriş bir sayı ise, ikinci giriş 1veya olmalıdır 0ve ardından ilk girişin dizi veya sayı olarak yorumlanması farketmez. Asıl sorun, ikinci girdi dizi boyutunu aşamaz. Msgstr "1 elemandan 2 eleman seçmenin kaç yolu var". Bu durumda dizi / sayı farkı önemlidir: eğer ilk girdi bir dizi dönüşü ise [](boş dizi), eğer bir sayı dönüşü ise 0. Sanırım geri döneceğim [], çünkü pdiğer yorumu zorlar
Luis Mendo

@FryAmTheEggman Sanırım işlevi iki versiyona bölerim. Tekrar teşekkürler!
Luis Mendo

3

Pyth, 15 13 12 11 bayt

*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)

Her bir bayt için @FryAmTheEggman ve @ Pietu1998'e teşekkürler !


1
* Boş bir dizideki F gerçekten 1 olmalıdır.
lirtosiast

3

Mathematica, 32 bayt

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

Vandermonde gibi şeyler için bir yapı bulunamamasına şaşırdım. Muhtemelen, bunu kendi başına yapmak çok kolaydır.

Bu, açıkça bir VM'nin devrik yapısını inşa eder ve onun belirleyicisini alır (elbette orijinalininkiyle aynıdır). Bu yöntemin bildiğim herhangi bir formülü kullanmaktan çok daha kısa olduğu ortaya çıktı.


3

Haskell, 34 bayt

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

Özyinelemeli bir çözüm. hCepheye yeni bir eleman hazırlandığında , ifade listedeki x-hher elemanın çarpımı ile çarpılır x. 1 bayt için Zgarb'a teşekkürler.


2

Matlab, 26 bayt

(Rakip olmayan)

Yerleşiklerin basit kullanımı. (Bir kez daha) Matlab'ın vander, Vandermonde matrisleri yarattığını, ancak sıraların ters çevrildiğini unutmayın.

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

2
Neden rekabet etmiyorsunuz?
Alex A.

3
Çünkü bu zorluğu yapan benim olduğum için, insanların kendi örneklerini deneyebilmeleri için sadece bunu sağlamak istedim.
kusurları

Det (çevrilmiş satırlar) = (-1) ^ n Det (orijinal) değil mi?
hYPotenuser

İki sütunu veya satırı değiştirdiğinizde belirleyici işaretleri imzaladığından emin değilim.
kusur,

@ hYPotenuser - n'yi n + 1 ile değiştirin. Yaptığınız tek şey, sol alttan üst sağa doğru giden diyagonal haricinde tümü sıfır olan bir matris P ile çarpmaktır (det (P * vander (v)) = det (P) det (vander (v) ))). İlk sütun boyunca ya da her neyse genişleterek, det (P) = (-1) ^ (n + 1) göreceksiniz.
Batman

2

Pas, 86 bayt

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

Pas, her zamanki gibi ayrıntılı ...

Açıklama daha sonra gelecek (yine de oldukça basit).


2

Perl, 38 41 bayt

İçin +1'i dahil et -p

Numaraları STDIN üzerindeki bir satıra verin. Yani, örneğin

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

Çift döngü elde etmek için kötü bir regex kullanın:

vandermonde.pl:

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

2

JavaScript (ES6), 61 bayt

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

Dizi anlama (Firefox 30-57) denedim ve 5 bayt daha uzundu:

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

Sıkıcı iç içe döngü olsa da muhtemelen daha kısadır.


1

Haskell, 53 bayt

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

Kullanım örneği: f [1,2,4,8,16]-> 20321280.

Endeksleri üzerinden gidin jve iiç içe bir döngüde ve pozisyonda elemanların farklılıkların bir listesini yapmak jve i. Listedeki tüm öğelerin ürününü yapın.

Biraz daha uzun olduğu ortaya çıkan diğer değişkenler:

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

import Data.List;f i=product[y-x|[x,y]<-subsequences i], 55 bayt


1

CJam, 16 bayt

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

A Simmons’ın görevine cevaben , CJam’ın bir kombinasyon operatörünün olmamasına rağmen, evet daha iyisini yapmak mümkündür :)

@ MartinBüttner sayesinde -1 bayt.

Çevrimiçi deneyin | Test odası

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 bayt

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

Birisinin CJam'da daha iyi golf oynayabileceğine eminim ... Asıl mesele, alt baytları almanın iyi bir yolunu görememem ve böylece baytlarımın çoğunu kullanabilmem. Bu güç setini üretir (Martin Büttner tarafından bir fikir kullanarak) ve sonra uzunluk-2 elemanlarını seçer.



Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.