반더 몬드 결정 인자


25

주어진 n값으로 구성된 벡터 (x1,x2,x3,...,xn)는 해당 Vandermonde 행렬 의 행렬식을 반환합니다 .

이 결정 요인은 다음과 같이 쓸 수 있습니다.

공식

세부

프로그램 / 함수는 가변 길이를 허용하고 지정된 결정자를 출력하는 편리한 형식의 부동 소수점 숫자 목록을 수용해야합니다.

입력과 출력이 언어가 지원하는 값 범위 내에 있다고 가정 할 수 있습니다. 언어가 부동 소수점 숫자를 지원하지 않으면 정수를 가정 할 수 있습니다.

일부 테스트 사례

두 개의 동일한 항목이있을 때마다 0해당 Vandermonde 매트릭스에 두 개의 동일한 행 이 있으므로 결정자가됩니다 . 이 누락 된 테스트 사례를 지적 한 @randomra에게 감사드립니다.

[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이됩니다.
flawr

1
@flawr 예상 출력이 사양에서 명확했습니다. 나는 테스트 케이스를 제안 했으므로 같은 숫자로 준비되지 않은 답변은 실수를보다 쉽게 ​​찾을 수 있습니다.
randomra

답변:


9

젤리, 6 바이트

œc2IFP

œc2길이 2를 바꾸지 않고 모든 조합을 가져 I옵니다. 각 쌍의 차이 목록을 계산하여와 같은 목록을 생성합니다 [[1], [2], [3], ..., [1]]. 우리는 F로프트를 빌려서 가져갑니다 P.

여기 사용해보십시오!


8

루비, 49 47 바이트

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

이것은 실제 값을 갖는 1 차원 배열을 받아들이고 입력 유형에 따라 float 또는 정수를 반환하는 람다 함수입니다. 그것을 호출하려면 변수에 할당 한 다음 수행하십시오 f.call(input).

우리는를 사용하여 크기 2의 모든 조합을 .combination(2)얻고를 사용하여 각 쌍의 차이를 얻습니다 .map {|a, b| b - a}. 결과 배열을로 구분 된 문자열에 조인 *한 다음 eval제품을 반환합니다. 입력의 길이가 1이면 이것은 nilRuby에서 거짓이므로이 ||1상황에서 마지막에 1을 ​​반환 할 수 있습니다 . 루비에서는 0이 진실이기 때문에 제품이 0 일 때도 여전히 작동합니다.

모든 테스트 사례를 온라인으로 확인

Doorknob 덕분에 2 바이트가 절약되었습니다!


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

J.에서 공백이 중요하지 않다고 생각했습니다.
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ 결정자 .는 수정 자 문자 이므로 분리 공백이 필요한 특수한 경우입니다 . :자체적으로 동일합니다 .
Zgarb

오! 멋지다.
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ 사실, 나는 그것이 J를 냉담하게 만드는 이유라고 생각합니다. J는 적 으면서, 즉 점이나 작은 링 (APL의 의미 처럼) J로두기 ... 놀라 울 정도로 과부하 .:(다시 시각적으로 두 개의 스택과 동일한하는 .S) (나를 위해) J 하드 읽을 수 있습니다. 점 옆의 공백이 의미를 결정할 때 얼마나 더 중요합니까! J의는 .컴퓨팅 역사의 모든에서 가장 과부하 상징한다 : 나는 53 별개의 의미를 계산 .(당신이 모든 계산하면 61 및 43 _9:에을 9:의 고유 한 의미를) :. kk. ;-)
Adám

@ 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 이상일 때 단일 값으로 만 작동하는 것 같습니다 ... 젤리를 이길려고 직접 작성했습니다 : P
FryAmTheEggman

@FryAmTheEggman Awww. 네 말이 맞아 고마워요!
Luis Mendo

그래, 나는 그것이 문제라고 생각했다. 난 당신이 얻을 때 래퍼를 추가하는 식으로 뭔가를하려고 생각 하는데요 Xn유사한 검사 할 if size(arg) == [1,1] ...또는 무언가를. 나는 소스를 구하기에는 너무 게으르지 만, (희망적으로) 그렇게 어렵지 않아야합니다.
FryAmTheEggman

@FryAmTheEggman 사실 그것이 문제인지 잘 모르겠습니다 (그래서 내 의견을 빠르게 편집 한 것입니다). 첫 번째 입력이 숫자이면 두 번째 입력은 1또는 이어야하며 0첫 번째 입력이 배열 또는 숫자로 해석 되더라도 차이가 없습니다. 실제 문제는 두 번째 입력이 배열 크기를 초과 할 수 없다는 것입니다. "1 요소 중 2 요소를 선택하는 방법은 몇 가지가 있습니까?" 이 경우 배열 / 숫자 차이는 중요합니다. 첫 번째 입력이 배열 반환 [](빈 배열)이면 숫자 반환 인 경우 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

수학, 32 바이트

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

나는 Vandermonde 물건을위한 내장을 찾지 못하는 것에 놀랐다. 아마도 스스로하기가 너무 쉽기 때문일 것입니다.

이것은 명시 적으로 VM의 전치를 구성하고 결정자를 취합니다 (물론 원본과 동일합니다). 이 방법은 내가 아는 공식을 사용하는 것보다 훨씬 짧은 것으로 나타났습니다.


3

하스켈, 34 바이트

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

재귀 솔루션. 새 요소 h앞에 앞에 추가하면 표현식 에 목록의 x-h각 요소 x에 대한 곱이 곱해집니다 . 1 바이트의 Zgarb에게 감사드립니다.


2

Matlab, 26 바이트

(비경쟁)

내장의 간단한 사용. Matlab vander은 Vandermonde 행렬을 만들지 만 행 순서를 뒤집어 놓았습니다.

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

2
왜 경쟁이 아닌가?
Alex A.

3
나는이 도전을 한 사람이기 때문에 사람들이 자신의 모범을 시험해 볼 수 있도록 이것을 제공하고 싶었습니다.
flawr

Det (flipped rows) = (-1) ^ n Det (original) 아닙니까?
hYPotenuser

두 개의 열이나 행을 전환 할 때마다 결정 스위치가 서명하므로 확실하지 않습니다.
flawr

@hYPotenuser-n을 n + 1로 바꿉니다. 당신이하고있는 일은 왼쪽 아래에서 오른쪽으로가는 대각선을 제외하고 모두 0 인 행렬 P를 곱하는 것입니다. 따라서 det (P * vander (v)) = det (P) det (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);

평소와 같이 녹, 장황 ...

설명은 나중에 올 것입니다 (그러나 매우 간단합니다).


2

펄, 38 41 바이트

에 +1 포함 -p

STDIN의 줄에 숫자를 적으십시오. 예를 들어

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

사악한 정규식을 사용하여 이중 루프를 얻으십시오.

vandermonde.pl:

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

2

자바 스크립트 (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

하스켈, 53 바이트

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

사용 예 : f [1,2,4,8,16]-> 20321280.

인덱스 ji중첩 루프를 살펴보고 위치 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

CJam의 조합 연산자 부족에도 불구하고 A Simmons의 게시물에 대한 답변으로 예, 더 잘 할 수 있습니다 :)

@ MartinBüttner 덕분에 -1 바이트.

온라인으로 사용해보십시오 | 테스트 스위트

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.