Tính biểu tượng Kronecker


9

Các liên kết có liên quan ở đâyđây , nhưng đây là phiên bản ngắn:

Bạn có đầu vào gồm hai số nguyên abgiữa vô cực âm và vô cực (mặc dù nếu cần, tôi có thể giới hạn phạm vi, nhưng hàm vẫn phải chấp nhận đầu vào âm).

Định nghĩa biểu tượng Kronecker

Bạn phải trả lại biểu tượng Kronecker (a|b)cho đầu vào abnơi

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

nơi b = p_1^e_1 * p_2^e_2 * ... * p_n^e_n, và p_ie_ilà số nguyên tố và số mũ trong nguyên tố của b.

Đối với một số nguyên tố lẻ p, (a|p)=a^((p-1)/2) (mod p)như được định nghĩa ở đây .

Đối với b == 2,(n|2)={0 for n even; 1 for n odd, n=+/-1 (mod 8); -1 for n odd, n=+/-3 (mod 8)

Đối với b == -1,(n|-1)={-1 for n<0; 1 for n>0

Nếu a >= b, (a|b) == (z|b)ở đâu z == a % b. Bởi tài sản này, và như được giải thích ở đâyở đây , alà một dư lượng bậc hai của bif z, mặc dù a >= b.

(-1|b)= 1nếu b == 0,1,2 (mod 4)-1nếu b == 3 (mod 4). (0|b)0ngoại trừ (0|1)đó là 1, bởi vì (a|1)luôn luôn 1và cho tiêu cực a, (-a|b) == (-1|b) * (a|b).

Đầu ra của biểu tượng Kronecker luôn luôn -1, 0 or 1, trong đó đầu ra là 0nếu abcó bất kỳ yếu tố chung nào. Nếu blà một số nguyên tố lẻ, (a|b) == 1nếu alà một dư lượng bậc hai mod b, và -1nếu là nó không phải là một dư lượng bậc hai.

Quy tắc

  • Mã của bạn phải là một chương trình hoặc một chức năng.

  • Các đầu vào phải theo thứ tự a b.

  • Các đầu ra phải là một trong hai -1, 0hoặc 1.

  • Đây là mã golf, vì vậy mã của bạn không cần phải hiệu quả, chỉ cần ngắn.

  • Không có tích hợp nào tính toán trực tiếp Kronecker hoặc các biểu tượng Jacobi và Legendre liên quan. Các phần mềm tích hợp khác (ví dụ: thừa số nguyên tố) là trò chơi công bằng.

Ví dụ

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

Đây là một chức năng phức tạp, vì vậy xin vui lòng cho tôi biết nếu có bất cứ điều gì không rõ ràng.


Bạn có chắc chắn không muốn không cho phép tích hợp? Reference.wolfram.com/lingu/ref/KroneckerSymbol.html
Martin Ender

@ MartinBüttner Tôi đã chỉnh sửa trong các ví dụ khi tôi thấy bình luận của bạn. Tôi sẽ không cho phép các phần tử tích hợp trực tiếp tính toán các ký hiệu Kronecker, Jacobi hoặc Legendre, nhưng mọi thứ khác (bao gồm các hàm thừa số nguyên tố) sẽ là trò chơi công bằng.
Sherlock9

Tôi không hoàn toàn chắc chắn tại sao (31 | 5) đưa ra 1. Không nên có dư lượng qudratic vậy tại sao không phải là -1?
Eumel

còn 7/19 nên là 1 và 19/7 nên là -1 theo wiki bạn đã liên kết
Eumel

3
Nếu các giải pháp phải xử lý chính xác các đầu vào âm và 0, bạn chắc chắn nên thêm một số trường hợp thử nghiệm cho điều đó.
Martin Ender

Câu trả lời:


2

CJam (70 byte)

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

Bản demo trực tuyến (các trường hợp thử nghiệm được tạo bằng Mathicala).

Mổ xẻ

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

Tôi đã tìm thấy một số cách đánh giá (a|2)cho cùng một số lượng ký tự và đã chọn sử dụng cách đánh giá rõ ràng nhất.

integer array <W= IMO là một cách thực hiện dự phòng khá tao nhã: nếu số nguyên lớn hơn độ dài của mảng, chúng tôi chọn phần tử cuối cùng.

Những bình luận khác

Thật đáng thất vọng vì với số nguyên tố kỳ lạ p, phong cách Fermat trực tiếp (a|p)rất ngắn, bởi vì có một cách rất hay để tìm kiếm (a|n)số lẻ tích cực nmà tôi muốn sử dụng. Cơ sở là bổ đề của Zolotarev:

Nếu plà một số nguyên tố lẻ và alà một số nguyên nguyên pthì biểu tượng Legendre (a|p)là dấu hiệu của hoán vịx -> ax (mod p)

Điều này đã được Frobenius củng cố để

Nếu ablà các số nguyên lẻ dương tương ứng thì biểu tượng Jacobi (a|b)là dấu hiệu của hoán vịx -> ax (mod b)

và bởi Lerch để

Nếu blà một số nguyên lẻ dương và alà một số nguyên nguyên tố bthì biểu tượng Jacobi (a|b)là dấu hiệu của hoán vịx -> ax (mod b)

Xem Brunyate và Clark, mở rộng cách tiếp cận Zolotarev-Frobenius đối với phương pháp đối ứng bậc hai , Tạp chí Ramanujan 37.1 (2014): 25-50 để tham khảo.

Và nó có thể dễ dàng được tăng cường thêm một bước nữa (mặc dù tôi chưa thấy điều này trong tài liệu)

Nếu blà một số nguyên lẻ dương và alà một số nguyên thì biểu tượng Jacobi (a|b)là biểu tượng Levi-Civita của bản đồ x -> ax (mod b).

Bằng chứng: nếu alà đồng thời bthì chúng ta sử dụng Zolotarev-Frobenius-Lerch; mặt khác, bản đồ không phải là một hoán vị và biểu tượng Levi-Civita là 0như mong muốn.

Điều này đưa ra phép tính biểu tượng Jacobi

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

Nhưng cách xử lý đặc biệt cần thiết (a|-1)(a|2)có nghĩa là tôi chưa tìm ra cách tính biểu tượng Kronecker ngắn hơn với cách tiếp cận này: nó ngắn hơn để nhân tố và xử lý các số nguyên tố riêng lẻ.


4

Python 3, 747 369 335 byte

Như một câu trả lời ví dụ, chỉ chơi golf một chút, và để cho bạn biết ý tưởng của một câu trả lời sẽ như thế nào.

Và đúng vậy, các yếu tố chính và các bit mã hóa độ dài chạy được đưa vào từ Pyth với lời xin lỗi tới 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
Lời xin lỗi được chấp nhận - Tôi rất vui khi ai đó đọc mã nguồn Pyth.
isaacg

2

Toán học, 169 175 165 byte

(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 Byte LabVIEW Nguyên thủy

Vì đối xứng của nó, tôi đã trao đổi các đầu vào nếu a lớn hơn b.

Đại diện cho công thức thực sự bây giờ

đếm như luôn luôn theo

cho trường hợp đúng


Thật không may, (a|b) != (b|a)trong mọi trường hợp. Trong hầu hết các trường hợp, có, nhưng không phải trong tất cả chúng. Mặc dù nó sẽ hoạt động nếu bạn giảm a mod bthay vì hoán đổi chúng.
Sherlock9

kể từ khi tôi có bản thám hiểm bây giờ tôi có thể chỉnh sửa nó, hãy cho tôi một phút
Eumel

1
Có cách nào tôi có thể kiểm tra điều này? Tôi thực sự không hiểu làm thế nào LabView hoạt động.
Sherlock9

đó là một câu hỏi hay, tôi có thể nghĩ ra 2 cách. Đầu tiên tôi có thể xây dựng một .exe và gửi nó cho bạn, thứ hai bạn có thể có phiên bản thử nghiệm labview và tôi có thể gửi cho bạn vi hoặc bạn có thể xây dựng lại từ pic.
Eumel

7
Đây không phải là 44 byte. Nếu bạn xác định một hệ thống tính điểm không dựa trên kích thước của tệp, bạn nên gọi nó là một cái gì đó không phải là byte.
frageum

1

Julia, 195 byte

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

Đây là hàm đệ quy kchấp nhận hai số nguyên và trả về một số nguyên.

Ung dung:

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 byte

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)

Có lẽ không hoàn toàn tối ưu hóa, nhưng một nỗ lực dũng cảm. Biểu tượng Kronecker được định nghĩa là hàm infix a # b, nghĩa là

*Main>323#455265 
1
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.