クロネッカー記号を計算する


9

ここここに関連リンクがありますが、ここに短いバージョンがあります:

2つの整数の入力がaありb、負の無限大と無限大の間にあります(必要な場合は範囲​​を制限できますが、関数は負の入力を受け入れる必要があります)。

クロネッカー記号の定義

(a|b)入力aおよびb場所のクロネッカーシンボルを返す必要があります

(a|b) = (a|p_1)^e_1 * (a|p_2)^e_2 * ... * (a|p_n)^e_n

ここでb = p_1^e_1 * p_2^e_2 * ... * p_n^e_n、およびp_iおよびe_iは、の素因数分解における素数と指数ですb

ここで定義されている奇数の素数のp場合。(a|p)=a^((p-1)/2) (mod p)

の場合b == 2(n|2)={0 for n even; 1 for n odd, n=+/-1 (mod 8); -1 for n odd, n=+/-3 (mod 8)

の場合b == -1(n|-1)={-1 for n<0; 1 for n>0

もしa >= b(a|b) == (z|b)どこz == a % b。このプロパティによって、そしてここここで説明さいるように、ifのa二次剰余です。bza >= b

(-1|b)= 1if b == 0,1,2 (mod 4)-1if b == 3 (mod 4)(0|b)である0ため除い(0|1)ているある1ので、(a|1)常に1、負のためa(-a|b) == (-1|b) * (a|b)

クロネッカーの記号の出力は常に-1, 0 or 1出力であり、0場合aおよびb任意の共通因子を持っています。場合はb、奇素数である(a|b) == 1場合aである平方剰余 MOD b、そして-1ある場合には、平方剰余ではありません。

ルール

  • コードはプログラムまたは関数でなければなりません。

  • 入力は次の順序でなければなりませんa b

  • 出力は-10またはのいずれかでなければなりません1

  • これはコードゴルフなので、コードは効率的である必要はありません。

  • クロネッカーまたは関連するヤコビ記号とルジャンドル記号を直接計算する組み込み関数はありません。他の組み込み(たとえば、素因数分解)は公平なゲームです。

>>> kronecker(1, 5)
1
>>> kronecker(3, 8)
-1
>>> kronecker(15, 22)
1
>>> kronecker(21, 7)
0
>>> kronecker(5, 31)
1
>>> kronecker(31, 5)
1
>>> kronecker(7, 19)
1
>>> kronecker(19, 7)
-1
>>> kronecker(323, 455625)
1
>>> kronecker(0, 12)
0
>>> kronecker(0, 1)
1
>>> kronecker(12, 0)
0
>>> kronecker(1, 0)
1
>>> kronecker(-1, 5)
1
>>> kronecker(1, -5)
1
>>> kronecker(-1, -5)
-1
>>> kronecker(6, 7)
-1
>>> kronecker(-1, -7)
1
>>> kronecker(-6, -7)
-1

これは複雑な機能ですので、不明な点があればお知らせください。


組み込みを禁止したくないですか?reference.wolfram.com/language/ref/KroneckerSymbol.html
Martin Ender 2015年

@MartinBüttner私はあなたのコメントを見たときに例で編集していました。クロネッカー、ヤコビ、またはルジャンドルのシンボルを直接計算するビルトインは許可しませんが、それ以外のもの(素因数分解関数を含む)は公平なゲームでなければなりません。
Sherlock9

(31 | 5)が1を与える理由は完全にはわかりません。四次剰余があるはずがないので、なぜ-1ではありませんか?
Eumel

また、リンクしたWikiによれば、7/19は1で、19/7は-1である必要があります
Eumel '30

3
ソリューションが負の入力とゼロの入力を正しく処理する必要がある場合は、そのためのテストケースを必ず追加する必要があります。
マーティンエンダー2015年

回答:


2

CJam(70バイト)

{_g\zmf+f{:P2+"W>2*(
z1=
;1
7&4-z[0W0X0]=
P%P+P(2/#P%_1>P*-"N/<W=~}:*}

オンラインデモ(Mathematicaで生成されたテストケース)。

解剖

{               e# Anonymous function. Stack: a b
  _g\zmf+       e# Factorise b, with special treatment for negatives
                e# CJam also gives special treatment to 0 and 1
                e# Stack: e.g. a [-1 2 2 5]; or a [-1 1]; or a [0 0]; or a [1 2 2 5]
  f{            e# For each "prime" factor P, find (a|P)
    :P2+        e# Extract code for P from an array formed by splitting a string
    "W>2*(      e#   a -> (a|-1)
z1=             e#   a -> (a|0)
;1              e#   a -> (a|1)
7&4-z[0W0X0]=   e#   a -> (a|2)
P%P+P(2/#P%_1>P*-" e# a -> (a|P) for odd prime P
    N/<W=~      e# Split string and select appropriate element
  }
  :*            e# Multiply the components together
}

(a|2)同じ文字数を評価するいくつかの方法を見つけ、最もわかりやすいプレゼンテーションを使用する方法を選択しました。

integer array <W= IMOはフォールバックを行う非常にエレガントな方法です。整数が配列の長さより大きい場合、最後の要素を選択します。

他のコメント

奇数の素数の場合p、直接フェルマースタイル(a|p)が非常に短いのは残念です。なぜなら、私が使用したかった(a|n)正の奇数nを見つける非常にゴルフの方法があるからです。基本はゾロタレフの補題です。

pが奇数の素数でa、整数の素数である場合p、ルジャンドル記号(a|p)は順列の符号ですx -> ax (mod p)

これはフロベニウスによって強化されました

もしab互いに素正の奇数の整数であるその後、ヤコビ記号は(a|b)順列の符号でありますx -> ax (mod b)

そしてLerchによって

場合はb正の奇数の整数であり、a整数の互いに素でありb、次いでヤコビ記号は、(a|b)順列の符号でありますx -> ax (mod b)

参照として、Brunanyate and Clark、Extending the Zolotarev-Frobenius approach to quadratic reciprocity、The Ramanujan Journal 37.1(2014):25-50を参照してください。

そして、それは簡単にさらに一歩強化することができます(私はこれを文献で見たことはありませんが)

場合はb正の奇数の整数であり、a整数であり、次いで、ヤコビシンボルは(a|b)マップのエディントンのイプシロンですx -> ax (mod b)

証明:a互いに素であれば、bZolotarev-Frobenius-Lerchを使用します。それ以外の場合、マップは順列ではなく、Levi-Civitaシンボルは0希望どおりです。

これは、ヤコビ記号計算を与えます

{_2m*{~>},@ff*\ff%::-:*g}

しかし、特別な治療が必要なため(a|-1)(a|2)、私はこのアプローチの短いクロネッカーの記号を計算する方法を発見していないことを意味:それはfactoriseに短いですし、個別の素数を扱います。


4

Python 3、747 369 335バイト

答えの例として、ほんの少しゴルフをし、答えがどのように見えるかについてのアイデアをあなたに与えるために。

そして、はい、素因数分解とランレングスエンコードビットはPythからisaacgへの謝罪で書かれています。

from itertools import*
def k(d,r):
 if d<0:a=-d;m=1
 else:a=d;m=0
 if r==1:return 1
 p=1;w=r;n=2;f=[]
 while n*n<=w:
  while w%n<1:w//=n;f+=n,
  n+=1
 if w>1:f+=w,
 z=[[k,len(list(g))]for k,g in groupby(f)]
 for i,j in z:
  if i==2:p*=pow(-1,(a*a-1)//8)
  x=pow(a,(i-1)//2,i)
  if x>1:x-=i
  p*=x**j
 if m:p*=pow(-1,(r-1)//2)
 return p

4
謝罪は受け入れられました-誰かがPythのソースコードを読んでよかったです。
isaacg 2015年

2

Mathematicaの、169の 175 165バイト

(1|-1)~k~0=_~k~1=1
_~k~0=0
a_~k~-1=If[a<0,-1,1]
a_~k~2=DirichletCharacter[8,2,a]
a_~k~p_/;PrimeQ@p=Mod[a^((p-1)/2),p,-1]
a_~k~b_:=1##&@@(a~k~#^#2&@@@FactorInteger@b)

2

LabVIEW、44バイトのLabVIEWプリミティブ

その対称的なので、aがbよりも大きい場合、私は入力を入れ替えました。

実際の数式を表す

いつものように数える

真実の場合


残念ながら、(a|b) != (b|a)すべてのケースで。ほとんどの場合、そうですが、すべてではありません。あなたがa mod bそれらを交換する代わりに削減した場合、それは機能しますが。
Sherlock9

エクスプランションができたので、編集できるようになりました。
少しお待ち

1
これをテストする方法はありますか?LabViewの仕組みがよくわかりません。
Sherlock9

それは良い質問です。2つの方法を考えることができます。最初に、.exeをビルドして送信できます。次に、labviewテストバージョンを取得して、viを送信するか、picから再ビルドできます。
Eumel 2015年

7
これは44バイトではありません。ファイルのサイズに基づいていないスコアリングシステムを定義する場合、それをバイト以外のものと呼ぶ必要があります。
feersum

1

ジュリア、195バイト

k(a,b)=b==0?a∈[1,-1]?1:0:b==1?1:b==2?iseven(a)?0:a%8∈[1,-1]?1:-1:b==-1?a<1?-1:1:isprime(b)&&b>2?a%b==0?0:a∈[i^2%b for i=0:b-1]?1:-1:k(a,sign(b))*prod(i->k(a,i)^factor(b)[i],keys(factor(b)))

これは、k2つの整数を受け入れ、整数を返す再帰関数です。

非ゴルフ:

function k(a::Integer, b::Integer)
    if b == 0
        return a  [1, -1] ? 1 : 0
    elseif b == 1
        return 1
    elseif b == 2
        return iseven(a) ? 0 : a % 8  [1, -1] ? 1 : -1
    elseif b == -1
        return a < 1 ? -1 : 1
    elseif isprime(b) && b > 2
        return a % b == 0 ? 0 : a  [i^2 % b for i = 1:b-1] ? 1 : -1
    else
        p = factor(b)
        return k(a, sign(b)) * prod(i -> k(a, i)^p[i], keys(p))
    end
end

1

Haskell、286バイト

a#0|abs a==1=1|1<2=0
a#1=1
a#2|even a=0|mod a 8`elem`[1,7]=1|1<2=(-1)
a#b|b<0=a`div`abs a*a#(-b)|all((/=0).mod b)[2..b-1]=if elem n[0,1] then n else(-1)|1<2=product$map(a#)$f b where n=a^(div(b-1)2)`mod`b
f 1=[]
f n|n<0=(-1):f(-n)|1<2=let p=head$filter((==0).mod n)[2..n]in p:f(div n p)

おそらく完全には最適化されていませんが、勇気ある努力です。クロネッカー記号は、中置関数a#bとして定義されます。

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