Rationalsの内積を見つける


31

私は友人の家に夕食に行って、彼らは「素因数ベクトル空間」のアイデアを提案しました。この空間では、正の整数はベクトルとして表現され、ベクトルのn番目の要素はn番目の素数が数を分割する回数になります。(これは、ベクトルに無限の数の項があることを意味することに注意してください。)たとえば、20

2 0 1 0 0 0 ...

その素因数分解は2 * 2 * 5であるためです。

素因数分解は一意であるため、各数値は1つのベクトルに対応します。

エントリをペアごとに追加することで、ベクトルを追加できます。これは、関連付けられている数値を乗算するのと同じです。また、スカラー乗算を行うこともできます。これは、関連する数値を累乗するようなものです。

問題は、逆行列がないため、この空間は実際にはベクトル空間ではないことです。先に進んで逆行列を追加してベクトル空間を閉じると、すべての正の有理数をベクトルとして表現する方法ができました。ベクトルの加算が乗算を表すという事実を保持する場合。そして、自然数の逆数はその逆数です。

たとえば、数20のベクトルは

2 0 1 0 0 0 ...

したがって、1/20の端数はその逆です

-2 0 -1 0 0 0 ...

我々のような割合に関連したベクトル見つけたい場合は14/15を我々は見つけるだろう14

1 0 0 1 0 0 ...

および1/15

0 -1 -1 0 0 0 ...

そして、ベクトル加算を実行してそれらを乗算します

1 -1 -1 1 0 0 ...

ベクトル空間ができたので、それを修正して内積を与えることにより内積空間を形成することができます。これを行うには、ベクトル空間が古典的に与えられているという内積を盗みます。2つのベクトルの内積は、それらの項のペアごとの乗算の合計として定義されます。たとえば、20・14/15 は次のように計算されます

20    =  2  0  1  0  0  0 ...
14/15 =  1 -1 -1  1  0  0 ...
         2  0 -1  0  0  0 ...  -> 1

別の例として、製品2/19・4/19

2/19 = 1 0 0 0 0 0 0 -1 0 0 0 ...
4/19 = 2 0 0 0 0 0 0 -1 0 0 0 ...
       2 0 0 0 0 0 0  1 0 0 0 ... -> 3

あなたの仕事は、この内積を実行するプログラムを実装することです。正の整数のペア(分子と分母)または有理型(浮動小数点は精度と割り切れる問題を引き起こすため許可されません)のいずれかを介して2つの正の有理数を取り、2つのドット積を表す整数を出力する必要があります入力。

これはため、回答はバイト単位で記録され、バイト数は少ない方が良いでしょう。

テストケース

4 · 4 = 4
8 · 8 = 9
10 · 10 = 2
12 · 12 = 5
4 · 1/4 = -4
20 · 14/15 = 1
2/19 · 4/19 = 3

ベクトルには次元がありませんが、ベクトル空間にはあります。
ジョナサンフレッチ

5
@JonathanFrech少しつまらなかったと思うが、変更を加えた。
小麦ウィザード

「自然数」には一般に0が含まれていると理解されていますが、これはシステムでは表されていません。そして、これらはベクトルではありません。ベクトル空間はフィールド上にあり、これはリング上にあり、これがモジュールになります。また、整数とは別のスペースではなく、表現が異なる同じスペースです。
累積

6
@Acccumulation「自然数」は明確に定義された用語ではありません。あなたが尋ねる人によっては、ゼロを含む場合と含まない場合があります。あなたは私の質問の「スカラー乗算」がグループではなくモノイドでG集合を形成することは正しいですが、それは質問を美味しくするために単純化されました。最後のコメントをどうすればいいのかわかりません。整数と同じカーディナリティを持っていることは確かですが、アクションは実際にはサイズではなくスペースを定義するものです。おそらく、あなたは私が見逃しているより具体的な何かを意味します。もしそうなら、私はこの議論を続けさせていただきたいと思います(チャットでの方が良いかもしれません)。
小麦ウィザード

2
別の用語nit-pick:ベクトル空間は一般にフィールドからのスカラー乗算を必要とするため、整数を使用するだけでは十分ではありません。これは、共通の倍数だけでなく、並列ベクトルを互いに倍数にする必要があるためです。たとえば、$ 4 $と$ 8 $はこの空間の並列「ベクトル」です(両方とも(a、0、0、...)の形式です)が、どちらもスカラー倍数(つまり整数のべき乗)ではありませんその他。ただし、他の多くの用語を使用できるわけではありませんが、一般に知られている用語です。「整数上の無料モジュール」が最善です。
アーサー

回答:


4

MATL、12バイト

YF2:&Y)dwd*s

入力は配列[num1 den1 num2 den2]です。

オンラインでお試しください!または、すべてのテストケースを確認します

説明

入力例を検討してください[20 1 14 15]

YF      % Implicit input: array of 4 numbers. Exponents of prime factorization.
        % Gives a matrix, where each row corresponds to one of the numbers in
        % the input array. Each row may contain zeros for non-present factors
        % STACK: [2 0 1 0
                  0 0 0 0
                  1 0 0 1
                  0 1 1 0]
2:&Y)   % Push a submatrix with the first two rows, then a submatrix with the
        % other two rows
        % STACK: [2 0 1 0
                  0 0 0 0],
                 [1 0 0 1
                  0 1 1 0]
d       % Consecutive difference(s) along each column
        % STACK: [2 0 1 0
                  0 0 0 0],
                 [-1 1 -1 1]
wd      % Swap, and do the same for the other submatrix
        % STACK: [-1 1 -1 1]
                 [-2 0 -1 0]
*       % Element-wise product
        % STACK: [2 0 -1 0]
s       % Sum. Implicit display
        % STACK: 1

4

C(gcc)、99 + 32 = 131バイト

  • 32バイトを必要とするコンパイラフラグを使用します-D=F(v,V,e)for(;v%p<1;V+=e)v/=p;
T,p,A,C;f(a,b,c,d){T=0;for(p=2;a+b+c+d>4;p++){A=C=0;F(a,A,1)F(b,A,~0)F(c,C,1)F(d,C,~0)T+=A*C;}a=T;}

オンラインでお試しください!


追加のフラグ-D=F(v,V,e)for(;v%p<1;V+=e)v/=p;(32バイト)が使用されるように明示的に指定する方がよいと思います(したがって99 + 32 = 131)。それ以外の場合、コードだけではほとんど意味がありません。
バブラー


3

Python 2、110バイト

l=input()
p=t=2
while~-max(l):r=i=0;exec"while l[i]%p<1:l[i]/=p;r+=1j**i\ni+=1\n"*4;t+=r*r;p+=1
print t.imag/2

オンラインでお試しください!

のような入力を受け取ります[num1, num2, den1, den2]。複素数を使用して、2つの有理数の r素数のエントリを格納し、合計内でそれらの積を抽出します。forを追加すると、4つの入力数値の実数部または虚数部のインクリメントまたはデクリメントの各組み合わせが行われます。p(r*r).imag/2r.real*r.imagt1j**ii=0,1,2,3

バブラーは、初期値を組み合わせて2バイトを節約しましたp=t=2


1
p=t=2とにかく、p=2;t=0sinceの代わりにt.real無視されます(TIO)。
バブラー

@Bubblerいいね、追加!
-xnor


1

JavaScript(Node.js)104 ... 100 94バイト

F=(A,i=2)=>A.some(x=>x>1)&&([a,b,c,d]=A.map(G=(x,j)=>x%i?0:1+G(A[j]/=i,j)),a-b)*(c-d)+F(A,i+1)

オンラインでお試しください!

[Num1、Den1、Num2、Den2]の配列として数値を渡します。

不足している問題を修正してくれたArnauldに感謝します F=余分なバイトなしでを、さらに2バイト少なくして。

説明と自由

function F(A, i = 2) {                 // Main function, recursing from i = 2
 if (A.some(function(x) {              // If not all numbers became 1:
  return x > 1;
 })) {
  var B = A.map(G = function(x, j) {   // A recursion to calculate the multiplicity
   if (x % i)
    return 0;
   else
    return 1 + G(A[j] /= i, j);        // ...and strip off all powers of i
  });
  return (B[0] - B[1]) * (B[2] - B[3]) // Product at i
   + F(A, i + 1);                      // Proceed to next factor. All composite factors 
 }                                     // will be skipped effectively
 else 
  return 0;                            // Implied in the short-circuit &&
}

1

J、19バイト

1#.*/@,:&([:-/_&q:)

オンラインでお試しください!

説明:

二項動詞、引数は左側と右側の両方にあります

         &(        ) - for both arguments (which are lists of 2 integers)
               _&q:  - decompose each number to a list of prime exponents
           [:-/      - and find the difference of these lists
       ,:            - laminate the resulting lists for both args (to have the same length)
   */@               - multiply them
1#.                  - add up 

1

Stax、11 バイト

ä÷ß½♂←√:=Ü]

実行してデバッグする

同じプログラムの対応するASCII表現はこれです。

{|nmMFE-~-,*+

基本的に、各部分の素因数分解の指数を取得します。各ペアの差、次に積を取り、最終的にすべての結果を合計します。


1

パイソン2133の 127バイト

a=input();s=0;p=2;P=lambda n,i=0:n%p and(n,i)or P(n/p,i+1)
while~-max(a):a,(w,x,y,z)=zip(*map(P,a));s+=(w-x)*(y-z);p+=1
print s

オンラインでお試しください!

xnorのsubmissionからループ条件を盗みました。

関数をプログラムに変更する@mathmandanのアドバイスをありがとう(はい、確かにいくつかのバイトを節約しました)。

廃止された誤ったソリューション(124バイト):

lambda w,x,y,z:sum((P(w,p)-P(x,p))*(P(y,p)-P(z,p))for p in[2]+range(3,w+x+y+z,2))
P=lambda n,p,i=1:n%p and i or P(n/p,p,i+1)

p9のような非素数の値をテストしませんか?
-xnor

すぐに修正します。
バブラー

3
あなたは置き換えることができreturnprint、そしてあなたの代わりに、関数のプログラムとして記述した場合、あなたはまた、インデントのスペースを節約することができます。
-mathmandan

@mathmandan情報をありがとう。私の他のPy2の投稿では有用に見えますが、Py3ではわかりません(eval()関数入力自体が文字列でない限り、余分にかかります)。
バブラー

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.