คำนวณสัญลักษณ์ Kronecker


9

ลิงก์ที่เกี่ยวข้องที่นี่และที่นี่แต่นี่เป็นเวอร์ชั่นย่อ:

คุณมีอินพุตของจำนวนเต็มสองจำนวนaและbระหว่างลบอนันต์และอินฟินิตี้ (แต่ถ้าจำเป็นฉันสามารถ จำกัด ช่วงได้ แต่ฟังก์ชั่นจะต้องยอมรับอินพุตลบ)

ความหมายของสัญลักษณ์ Kronecker

คุณต้องส่งคืนสัญลักษณ์ Kronecker (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_ib

สำหรับคี่สำคัญ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โดยสถานที่นี้และตามที่อธิบายไว้ที่นี่และที่นี่ , aเป็นสารตกค้างกำลังสองของbถ้าคือแม้ว่าza >= b

(-1|b)= 1ถ้าb == 0,1,2 (mod 4)และถ้า-1 คือยกเว้นซึ่งเป็นเพราะอยู่เสมอและเชิงลบ,b == 3 (mod 4)(0|b)0(0|1)1(a|1)1a(-a|b) == (-1|b) * (a|b)

เอาต์พุตของสัญลักษณ์ Kronecker อยู่เสมอ-1, 0 or 1โดยที่เอาต์พุตคือ0ถ้าaและbมีปัจจัยทั่วไป ถ้าbเป็นนายกแปลก(a|b) == 1ถ้าaเป็นสารตกค้างกำลังสองสมัยbและ-1ถ้ามันไม่ได้เป็นสารตกค้างกำลังสอง

กฎระเบียบ

  • รหัสของคุณจะต้องเป็นโปรแกรมหรือฟังก์ชั่น

  • a bปัจจัยการผลิตจะต้องอยู่ในการสั่งซื้อ

  • การส่งออกจะต้องเป็นอย่างใดอย่างหนึ่ง-1, หรือ01

  • นี่คือรหัสกอล์ฟดังนั้นรหัสของคุณไม่จำเป็นต้องมีประสิทธิภาพแค่ช่วงสั้น ๆ

  • ไม่มีบิวด์อินที่คำนวณสัญลักษณ์ Kronecker หรือสัญลักษณ์ Jacobi และ Legendre ที่เกี่ยวข้องโดยตรง บิวด์อินอื่น ๆ (สำหรับการแยกตัวประกอบเฉพาะ) เป็นเกมที่ยุติธรรม

ตัวอย่าง

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

@ MartinBüttnerฉันแก้ไขในตัวอย่างเมื่อฉันเห็นความคิดเห็นของคุณ ฉันจะไม่อนุญาตบิวด์อินที่คำนวณสัญลักษณ์ Kronecker, Jacobi หรือ Legendre โดยตรง แต่สิ่งอื่น ๆ (รวมถึงฟังก์ชั่นการแยกตัวประกอบเฉพาะ) ควรเป็นเกมที่ยุติธรรม
Sherlock9

ฉันไม่แน่ใจทั้งหมดว่าทำไม (31 | 5) ให้ 1 ไม่ควรมีเศษ qudratic ดังนั้นทำไมมันไม่ -1
Eumel

นอกจากนี้ 7/19 ควรเป็น 1 และ 19/7 ควรเป็น -1 ตามวิกิที่คุณเชื่อมโยง
Eumel

3
หากวิธีการแก้ปัญหาต้องจัดการกับอินพุตเชิงลบและเป็นศูนย์อย่างถูกต้องคุณควรเพิ่มกรณีทดสอบบางกรณี
Martin Ender

คำตอบ:


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ที่ฉันต้องการใช้ พื้นฐานคือบทแทรกของ Zolotarev:

ถ้าpเป็นไพรเมอร์แปลก ๆ และaเป็นจำนวนเต็ม coprime pสัญลักษณ์ Legendre (a|p)เป็นสัญลักษณ์ของการเปลี่ยนแปลงx -> ax (mod p)

สิ่งนี้ได้รับความเข้มแข็งจาก Frobenius ถึง

ถ้าaและbเป็นจำนวนเต็มคี่บวก coprime บวกแล้วสัญลักษณ์ Jacobi (a|b)เป็นสัญลักษณ์ของการเปลี่ยนแปลงx -> ax (mod b)

และโดย Lerch ถึง

ถ้าbเป็นจำนวนเต็มคี่บวกและaเป็นจำนวนเต็ม coprime bดังนั้นสัญลักษณ์ Jacobi (a|b)เป็นสัญลักษณ์ของการเปลี่ยนแปลงx -> ax (mod b)

ดู Brunyate และ Clark ขยายวิธีการ Zolotarev-Frobenius ไปสู่การแลกเปลี่ยนซึ่งกันและกันกำลังสองวารสาร Ramanujan 37.1 (2014): 25-50 สำหรับการอ้างอิง

และสามารถเพิ่มความแข็งแกร่งได้ง่ายขึ้นอีกขั้นหนึ่ง (แม้ว่าฉันจะไม่ได้เห็นสิ่งนี้ในวรรณคดี)

ถ้าbเป็นจำนวนเต็มคี่บวกและaเป็นจำนวนเต็มแล้ว Jacobi สัญลักษณ์(a|b)เป็นสัญลักษณ์ Levi-Civita x -> ax (mod b)ของแผนที่

หลักฐาน: ถ้าaเป็น coprime bเราจะใช้ Zolotarev-Frobenius-Lerch มิฉะนั้นแผนที่ไม่ใช่การเปลี่ยนแปลงและสัญลักษณ์ Levi-Civita เป็นไป0ตามที่ต้องการ

สิ่งนี้ทำให้การคำนวณสัญลักษณ์ Jacobi

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

แต่การรักษาพิเศษที่จำเป็น(a|-1)และ(a|2)หมายความว่าฉันไม่พบวิธีคำนวณสัญลักษณ์ Kronecker ซึ่งสั้นกว่าด้วยวิธีนี้: มันสั้นกว่าที่จะแยกตัวประกอบและปฏิบัติเฉพาะช่วงเวลา


4

Python 3, 747 369 335 bytes

ตัวอย่างคำตอบเพียงแค่ตีกอล์ฟเพียงเล็กน้อยและเพื่อให้คุณเข้าใจว่าคำตอบจะเป็นอย่างไร

และใช่ตัวประกอบนายกรัฐมนตรีและระยะยาวเข้ารหัสบิต cribbed จาก 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

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 ไบต์Primitives LabVIEW

ตั้งแต่ symetrical ของมันฉันสลับอินพุตถ้า a นั้นใหญ่กว่า b

แสดงถึงสูตรที่แท้จริงในขณะนี้

การนับเช่นเคยเป็นไปตาม

สำหรับกรณีจริง


น่าเสียดายที่(a|b) != (b|a)ในทุกกรณี ในกรณีส่วนใหญ่ใช่ แต่ไม่ใช่ทั้งหมด แม้ว่ามันจะใช้ได้ผลถ้าคุณลดa mod bแทนที่จะเปลี่ยนมัน
Sherlock9

เนื่องจากฉันมี explantion ตอนนี้ฉันสามารถแก้ไขได้ให้ฉันนาที
Eumel

1
มีวิธีใดที่ฉันสามารถทดสอบได้หรือไม่ ฉันไม่เข้าใจว่า LabView ทำงานอย่างไร
Sherlock9

นั่นเป็นคำถามที่ดีฉันสามารถคิดได้ 2 วิธี ก่อนอื่นฉันสามารถสร้าง. exe และส่งมาให้คุณอันดับที่สองคุณสามารถรับรุ่นทดสอบ labview และฉันสามารถส่ง vi หรือสร้างใหม่จากรูปได้
Eumel

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

นี่เป็นฟังก์ชันแบบเรียกซ้ำkที่ยอมรับจำนวนเต็มสองจำนวนและส่งกลับจำนวนเต็ม

Ungolfed:

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)

อาจไม่ได้รับการปรับปรุงอย่างสมบูรณ์ แต่เป็นความพยายามที่กล้าหาญ สัญลักษณ์ Kronecker ถูกกำหนดให้เป็นฟังก์ชั่นมัด a # b คือ

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