Công thức kiểm tra tính nguyên thủy


30

Mục tiêu của bạn là xác định xem một số đã cho ncó phải là số nguyên tố trong vài byte hay không. Nhưng, mã của bạn phải là một biểu thức Python 2 duy nhất trên các số chỉ bao gồm

  • khai thác
  • biến đầu vào n
  • hằng số nguyên
  • dấu ngoặc đơn

Không vòng lặp, không bài tập, không có chức năng tích hợp, chỉ những gì được liệt kê ở trên. Vâng nó có thể.

Người vận hành

Dưới đây là danh sách tất cả các toán tử trong Python 2 , bao gồm các toán tử số học, bitwise và logic:

+    adddition
-    minus or unary negation
*    multiplication
**   exponentiation, only with non-negative exponent
/    floor division
%    modulo
<<   bit shift left
>>   bit shift right
&    bitwise and
|    bitwise or
^    bitwise xor
~    bitwise not
<    less than
>    greater than
<=   less than or equals
>=   greater than or equals
==   equals
!=   does not equal

Tất cả các giá trị trung gian là số nguyên (hoặc Sai / Đúng, hoàn toàn bằng 0 và 1). Lũy thừa có thể không được sử dụng với số mũ âm, vì điều này có thể tạo ra phao. Lưu ý rằng /không phân chia tầng, không giống như Python 3, vì vậy //không cần thiết.

Ngay cả khi bạn không quen thuộc với Python, các toán tử sẽ khá trực quan. Xem bảng này để biết mức độ ưu tiên của toán tửphần này và bên dưới để biết thông số kỹ thuật chi tiết về ngữ pháp. Bạn có thể chạy Python 2 trên TIO .

Tôi / O

Đầu vào: Một số nguyên dương ncó ít nhất 2.

Đầu ra: 1 nếu nlà số nguyên tố và 0 nếu không. TrueFalsecũng có thể được sử dụng. Ít byte nhất sẽ thắng.

Vì mã của bạn là một biểu thức, nó sẽ là một đoạn mã, mong đợi giá trị đầu vào được lưu dưới dạng nvà đánh giá đầu ra mong muốn.

Mã của bạn phải làm việc cho nlớn tùy ý, giới hạn hệ thống sang một bên. Vì loại số nguyên của Python không bị ràng buộc, nên không có giới hạn đối với các toán tử. Mã của bạn có thể mất nhiều thời gian để chạy.


Có lẽ điều này nên có thẻ python?
fnɛtɪk

Câu trả lời:


35

43 byte

(4**n+1)**n%4**n**2/n&2**(2*n*n+n)/-~2**n<1

Hãy thử trực tuyến!

Phương pháp này tương tự như câu trả lời thứ hai (đã xóa) của Dennis, nhưng câu trả lời này dễ được chứng minh là đúng.

Bằng chứng

Hình thức ngắn

Chữ số có ý nghĩa nhất (4**n+1)**n%4**n**2trong cơ sở không chia hết cho n sẽ tạo ra chữ số tiếp theo (ít có ý nghĩa) trong sốkhác (nếu "chữ số tiếp theo" không nằm trong phần phân số), thì avới bitmaskđược thực thi để kiểm tra nếu bất kỳ chữ số nào ở vị trí lẻ là khác không.2nn(4**n+1)**n%4**n**2/n&2**(2*n*n+n)/-~2**n

Hình thức dài

Hãy là số có mà cơ sở b đại diện, ví dụ, một n b n + + một 1 b 1 + một 0 b 0 , và một i là chữ số tại " vị trí " i trong cơ sở b đại diện.[an,,a1,a0]bbanbn++a1b1+a0b0aiib

  • .2**(2*n*n+n)/-~2**n=2(2n+1)n1+2n=4n2×2n1+2n=(4n21)×2n1+2n+2n1+2n

(vớin2n-1s) là một số nguyên và2n2n×4n211+2n=2n(2n1)×(4n)n14n1=[2n1,0,2n1,0,2n1,0]2nn 2n1, =[2n-1,0,2n-1,0,2n-1,0]2n.2n1+2n=02**(2*n*n+n)/-~2**n[2n1,0,2n1,0,2n1,0]2n

Tiếp theo, hãy xem xét

(4**n+1)**n=(4n+1)n=(n0)40n+(n1)41n++(nn)4n2=[(nn),0,,0,(n1),0,(n0)]2n

, do đósẽ cắt số thành 2 n chữ số cuối - loại trừ ( n4n2=(2n)2n%4**n**22n (là 1) nhưng bao gồm tất cả các hệ số nhị thức khác.(nn)

Về /n:

  • Nếu là số nguyên tố, kết quả sẽ là [ ( nn. Tất cả các chữ số ở vị trí lẻ bằng không.[(nn1)/n,0,,0,(n1)/n,0,0]2n

  • Nếu không phải là số nguyên tố:n

    Đặt là số nguyên lớn nhất sao cho n ( na (n>a>0). Viết lại cổ tức nhưn(na)n>a>0

    [(nn1),0,(nn2),0,,(na+1),0,0,0,,0,0,0]2n+[(na),0,(na1),0,,(n0)]2n

    Triệu hồi đầu tiên có tất cả các chữ số chia hết cho và chữ số ở vị trí 2 a - 1 zero.n2a1

    Triệu hồi thứ hai có chữ số có nghĩa nhất (ở vị trí ) không chia hết cho n và (cơ sở) 2 n > n , do đó, thương số khi chia cho n sẽ có chữ số ở vị trí 2 a - 1 khác.2an2n>nn2a1

    Do đó, kết quả cuối cùng ( (4**n+1)**n%4**n**2/n) nên có chữ số (cơ sở , tất nhiên) ở vị trí 2 a + 1 khác không.2n2a+1

Cuối cùng, bitwise AND ( &) thực hiện một bit theo vectơ AND trên các chữ số trong cơ sở (vì cơ sở là lũy thừa của 2) và vì a & 0 = 0 , a & ( 2 n - 1 ) = a cho tất cả 0 một < 2 n , là số không khi và chỉ khi có đầy đủ chữ số trong đầu n vị trí lẻ zero - tương đương với n là số nguyên tố.2na&0=0,a&(2n1)=a0a<2n(4**n+1)**n%4**n**2/n&2**(2*n*n+n)/-~2**n(4**n+1)**n%4**n**2/nnn


2
Sẽ (4**n+1)**n%2**n**2/n&2**n**2/-~2**n<1làm việc?
Dennis

11
Nếu thật dễ dàng để chứng minh chính xác, bạn có thể đưa bằng chứng vào câu trả lời không? Hiện tại chúng tôi có MathJax, vì vậy việc chứng minh bằng chứng dễ đọc là tương đối dễ dàng và tôi không thể thấy lý do rõ ràng cho việc phân chia bằng cách nkhông gây ra các tương tác không mong muốn giữa các chữ số cơ sở 4**n.
Peter Taylor

3
"Tôi đã phát hiện ra một bằng chứng thực sự đáng chú ý về câu trả lời này mà bình luận này quá nhỏ để chứa ..."
Chấn thương kỹ thuật số

1
Đề nghị rút ngắn bằng chứng được chào đón.
dùng202729

1
Làm tốt lắm! Đây là cùng một giải pháp tôi đã đưa ra. Tôi tìm thấy một vài byte có thể được cắt bằng (4**n+1)**n%4**n**2/n<<n&4**n**2/-~2**n<1. Tôi tò mò nếu thử thách này là có thể mà không cần các nhà khai thác bitwise.
xnor

6

Python 2 , 56 byte

n**(n*n-n)/(((2**n**n+1)**n**n>>n**n*~-n)%2**n**n)%n>n-2

Hãy thử trực tuyến!

Đây là một bằng chứng của khái niệm rằng thách thức này là doable với chỉ toán tử số học, đặc biệt là không Bitwise |, &hoặc ^. Mã này sử dụng các toán tử bitwise và so sánh chỉ để chơi gôn và chúng có thể dễ dàng được thay thế bằng các số tương đương số học.

n=62nn

n!(n1)!%n>n2%

Chúng ta có thể tạo biểu thức cho hệ số nhị thức , được tạo thành từ các yếu tố

(mn) =m!n!(mn)!

n!m

(mn) =m(m1)(mn+1)n!=mnn!(11m)(12m)(1n1m)

c(11m)(12m)(1n1m)

n!=mn(mn)c

cm

c1mmcn!

n!=mn(mn)

1c<1/n!n!+1

cn(1n1m)

c>(1n1m)n>1n1mn>1n2m,

1c<n2m1c<1/n!mn!n2

m=nn(n1)!m(n1)!(n1)2m=nn


3

1i,j<ni×j=n

Python 2, cách quá nhiều byte (278 nhờ Jo King trong các bình luận!)

((((((2**(n*n)/(2**n-1)**2)*(2**((n**2)*n)/(2**(n**2)-1)**2))^((n*((2**(n*n-n)/(2**n-1))*(2**((n**2)*(n-1))/(2**n**2-1))))))-((2**(n*n-n)/(2**n-1))*(2**((n**2)*(n-1))/(2**(n**2)-1))))&(((2**(n*(n-1))/(2**n-1))*(2**((n**2)*(n-1))/(2**(n**2)-1)))*(2**(n-1)))==0))|((1<n<6)&(n!=4))

Hãy thử trực tuyến!

Đây là nhiều byte hơn so với các câu trả lời khác, vì vậy bây giờ tôi sẽ bỏ qua nó. Đoạn mã dưới đây chứa các hàm và gán biến cho rõ ràng, nhưng thay thế biến isPrime (n) thành một biểu thức Python duy nhất.

def count(k, spacing):
    return 2**(spacing*(k+1))/(2**spacing - 1)**2
def ones(k, spacing):
    return 2**(spacing*k)/(2**spacing - 1)

def isPrime(n):
    x = count(n-1, n)
    y = count(n-1, n**2)
    onebits = ones(n-1, n) * ones(n-1, n**2)
    comparison = n*onebits
    difference = (x*y) ^ (comparison)
    differenceMinusOne = difference - onebits
    checkbits = onebits*(2**(n-1))
    return (differenceMinusOne & checkbits == 0 and n>1)or 1<n<6 and n!=4

Tại sao nó hoạt động?

Tôi sẽ làm cùng một thuật toán ở đây trong cơ sở 10 thay vì nhị phân. Nhìn vào phần gọn gàng này:

1.09992=1.002003004005

1015/(9992)=10020030041,2,3,4

Giả sử chúng ta nhân hai số như thế này, với các khoảng không khác nhau. Tôi sẽ đặt dấu phẩy một cách gợi ý trong sản phẩm.

1002003004×1000000000002000000000003000000000004=
1002003004,002004006008,003006009012,004008012016

005

005005005005001001001001d005999d

d900900900900


1
Một bản in nhanh của biểu thức đặt điều này ở mức 278 byte (mặc dù tôi chắc chắn rất nhiều dấu ngoặc đơn không cần thiết)
Jo King
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.