Đây có phải là số Proth không?


37

Một số Proth , được đặt tên theo François Proth, là một số có thể được biểu thị là

N = k * 2^n + 1

Trường hợp klà một số nguyên dương lẻ và nlà một số nguyên dương sao cho 2^n > k. Hãy sử dụng một ví dụ cụ thể hơn. Lấy 3. 3 là số Proth vì nó có thể được viết là

(1 * 2^1) + 1

2^1 > 1hài lòng. 5 cũng là một số Proth vì nó có thể được viết là

(1 * 2^2) + 1

2^2 > 1hài lòng. Tuy nhiên, 7 không phải là số Proth vì cách duy nhất để viết nó theo mẫu N = k * 2^n + 1

(3 * 2^1) + 1

2^1 > 3không hài lòng.

Thử thách của bạn khá đơn giản: bạn phải viết một chương trình hoặc hàm, được đưa ra một số nguyên định nghĩa, xác định xem đó có phải là số Proth hay không. Bạn có thể lấy đầu vào ở bất kỳ định dạng hợp lý nào và nên xuất giá trị trung thực nếu đó là số Proth và giá trị giả nếu không. Nếu ngôn ngữ của bạn có bất kỳ chức năng "Phát hiện số Proth" nào, bạn có thể sử dụng chúng.

Kiểm tra IO

Dưới đây là 46 số Proth đầu tiên lên tới 1000. ( A080075 )

3, 5, 9, 13, 17, 25, 33, 41, 49, 57, 65, 81, 97, 113, 129, 145, 161, 177, 193, 209, 225, 241, 257, 289, 321, 353, 385, 417, 449, 481, 513, 545, 577, 609, 641, 673, 705, 737, 769, 801, 833, 865, 897, 929, 961, 993

Mỗi đầu vào hợp lệ khác sẽ cung cấp một giá trị giả.

Như thường lệ, đây là môn đánh gôn, do đó, sơ hở tiêu chuẩn được áp dụng và câu trả lời ngắn nhất bằng byte sẽ thắng!


Lý thuyết số vui-thực tế bên lưu ý:

Số nguyên tố lớn nhất được biết đến mà không phải là Mersenne Prime 19249 * 2^13018586 + 1, điều này cũng xảy ra cũng là một số Proth!

Câu trả lời:


41

Thạch , 5 byte

’&C²>

Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

Lý lịch

Đặt j là số nguyên dương hoàn toàn. j + 1 bật tắt tất cả các bit đặt cuối của j và bit unset liền kề. Ví dụ: 10011 2 + 1 = 10100 2 .

~ j = - (j + 1) = -j - 1 , -j = ~ j + 1 , vì vậy -n áp dụng cách trên cho bitwise KHÔNG của j (làm tắt tất cả các bit), do đó chuyển đổi tất cả các bit trước lần cuối cùng 1 .

Bằng cách lấy j & -j - bitwise AND của j-j - tất cả các bit trước và sau bit đặt cuối cùng đều bị vô hiệu hóa (vì không bằng nhau trong j-j ), do đó mang lại công suất cao nhất là 2 chia đều cho j .

Đối với đầu vào N , chúng tôi muốn áp dụng cách trên cho N - 1 để tìm 2 n , công suất cao nhất là 2 chia cho N - 1 . Nếu m = N - 1 , -m = - (N - 1) = 1 - N , do đó (N - 1) & (1 - N) mang lại 2 n .

Tất cả những gì còn lại để kiểm tra là nếu 2 n > k . Nếu k> 0 , điều này là đúng khi và chỉ khi (2 n ) 2 > k2 n , đó là sự thật chính nó nếu và chỉ nếu (2 n ) 2 ≥ k2 n + 1 = N .

Cuối cùng, nếu (2 n ) 2 = N = k2 n + 1 , 2 n phải là số lẻ ( 1 ) để các chẵn lẻ của cả hai bên có thể khớp với nhau, ngụ ý rằng k = 0N = 1 . Trong trường hợp này (N - 1) & (1 - N) = 0 & 0 = 0((N - 1) & (1 - N)) 2 = 0 <1 = N .

Do đó, ((N - 1) & (1 - N)) 2 > N là đúng khi và chỉ khi N là số Proth.

Làm thế nào nó hoạt động

’&C²>  Main link. Argument: N

’      Decrement; yield N - 1.
  C    Complement; yield 1 - N.
 &     Take the bitwise AND of both results.
   ²   Square the bitwise AND.
    >  Compare the square to N.

woah thật không thể tin được
don sáng

46

Python, 22 byte

lambda N:N-1&1-N>N**.5

Đây là một cổng của câu trả lời Jelly của tôi . Kiểm tra nó trên Ideone .

Làm thế nào nó hoạt động

Đặt j là số nguyên dương hoàn toàn. j + 1 bật tắt tất cả các bit đặt cuối của j và bit unset liền kề. Ví dụ: 10011 2 + 1 = 10100 2 .

~ j = - (j + 1) = -j - 1 , -j = ~ j + 1 , vì vậy -n áp dụng cách trên cho bitwise KHÔNG của j (làm tắt tất cả các bit), do đó chuyển đổi tất cả các bit trước lần cuối cùng 1 .

Bằng cách lấy j & -j - bitwise AND của j-j - tất cả các bit trước và sau bit đặt cuối cùng đều bị vô hiệu hóa (vì không bằng nhau trong j-j ), do đó mang lại công suất cao nhất là 2 chia đều cho j .

Đối với đầu vào N , chúng tôi muốn áp dụng cách trên cho N - 1 để tìm 2 n , công suất cao nhất là 2 chia cho N - 1 . Nếu m = N - 1 , -m = - (N - 1) = 1 - N , do đó (N - 1) & (1 - N) mang lại 2 n .

Tất cả những gì còn lại để kiểm tra là nếu 2 n > k . Nếu k> 0 , điều này là đúng khi và chỉ khi (2 n ) 2 > k2 n , đó là sự thật chính nó nếu và chỉ nếu (2 n ) 2 ≥ k2 n + 1 = N .

Cuối cùng, nếu (2 n ) 2 = N = k2 n + 1 , 2 n phải là số lẻ ( 1 ) để các chẵn lẻ của cả hai bên có thể khớp với nhau, ngụ ý rằng k = 0N = 1 . Trong trường hợp này (N - 1) & (1 - N) = 0 & 0 = 0((N - 1) & (1 - N)) 2 = 0 <1 = N .

Do đó, ((N - 1) & (1 - N)) 2 > N là đúng khi và chỉ khi N là số Proth.

Bỏ qua những điểm không chính xác, dấu phẩy này tương đương với mã N-1&1-N>N**.5trong phần thực hiện.


23
Tôi thường xuyên sử dụng Math.SE và đôi mắt của tôi thực sự mong muốn LaTeX đẹp trên trang web này thay vì trông giống như một trang web của thập niên 90 ...
qwr

Đây là một yêu thích của tôi.
Qix


9

Toán học, 50 48 45 40 38 35 31 29 byte

Mathicala thường rất tệ khi chơi golf, nhưng đôi khi có một công cụ tích hợp giúp mọi thứ trông thật sự đẹp.

1<#<4^IntegerExponent[#-1,2]&

Một thử nghiệm:

Reap[Do[If[f[i],Sow[i]],{i,1,1000}]][[2,1]]

{3, 5, 9, 13, 17, 25, 33, 41, 49, 57, 65, 81, 97, 113, 129, 145, 161, 177, 193, 209, 225, 241, 257, 289, 321, 353, 385, 417, 449, 481, 513, 545, 577, 609, 641, 673, 705, 737, 769, 801, 833, 865, 897, 929, 961, 993}

Chỉnh sửa: Trên thực tế, nếu tôi ăn cắp ý tưởng VÀ bit của Dennis , tôi có thể giảm xuống còn 23 22 20 byte.

Mathicala, 23 22 20 byte (cảm ơn A Simmons )

BitAnd[#-1,1-#]^2>#&

2
Chào mừng bạn đến với Câu đố lập trình và Code Golf! :)
Ad Nam

1
Không cần phải bắt đầu g=, một chức năng thuần túy là tốt!
Một Simmons

Ôi, ngọt ngào. Đã sửa nó ngay.
Michael Lee

Nhân tiện, bài kiểm tra của bạn có thể được đơn giản hóa đáng kể Select[Range@1000,f].
numbermaniac

8

05AB1E , 14 10 byte

Cảm ơn Emigna vì đã tiết kiệm 4 byte!

Mã số:

<©Ó¬oD®s/›

Sử dụng mã hóa CP-1252 . Hãy thử trực tuyến! .

Giải trình:

Để giải thích, chúng ta hãy sử dụng số 241 . Trước tiên, chúng tôi giảm số lượng với một <. Kết quả là 240 . Bây giờ, chúng tôi tính toán các yếu tố chính (với các bản sao) bằng cách sử dụng Ò. Các yếu tố chính là:

[2, 2, 2, 2, 3, 5]

Chúng tôi chia chúng thành hai phần. Sử dụng 2Q·0K, chúng tôi nhận được danh sách của hai:

[2, 2, 2, 2]

Với ®2K, chúng tôi nhận được danh sách các số còn lại:

[3, 5]

Cuối cùng, lấy sản phẩm của cả hai. [2, 2, 2, 2]kết quả thành 16 . Sản phẩm của [3, 5]kết quả thành 15 .

Trường hợp thử nghiệm này là sự thật kể từ 16 > 15 .


<©Ó¬oD®s/›hoặc <DÓ0èoDŠ/›cho 10.
Emigna

@Emigna Đó là thiên tài! Cảm ơn :).
Ad Nam

7

Brain-Flak , 460 350 270 266 264 188 176 byte

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

({}[()])(((<>()))){{}([(((({}<(({}){})>){}){})<>[({})(())])](<>)){({}())<>}{}<>{}{}<>(({})){{}{}<>(<(())>)}{}}(<{}{}>)<>{({}[()])<>(({}()[({})])){{}(<({}({}))>)}{}<>}{}<>({}<>)

Giải trình

Chương trình trải qua sức mạnh của hai và bốn cho đến khi tìm thấy sức mạnh của hai lớn hơn N-1. Khi tìm thấy nó, nó kiểm tra tính phân chia của N-1 bằng sức mạnh của hai bằng cách sử dụng modulo và đưa ra kết quả

({}[()])      #Subtract one from input
(((<>())))    #Put three ones on the other stack
{
 {}           #Pop the crap off the top
 ([(
  ((({}<(({}){})>){}){}) #Multiply the top by four and the bottom by two
  <>[({})(())])](<>)){({}())<>}{}<>{}{}<>(({})){{}{}<>(<(())>)}{} #Check if the power of four is greater than N-1
}
(<{}{}>) #Remove the power of 4
<>{({}[()])<>(({}()[({})])){{}(<({}({}))>)}{}<>}{}<>({}<{}><>) #Modulo N-1 by the power of two

Chương trình này không phải là ngăn xếp sạch sẽ. Nếu bạn thêm 4 byte, bạn có thể làm cho nó ngăn xếp sạch sẽ:

({}[()])(((<>()))){{}([(((({}<(({}){})>){}){})<>[({})(())])](<>)){({}())<>}{}<>{}{}<>(({})){{}{}<>(<(())>)}{}}(<{}{}>)<>{({}[()])<>(({}()[({})])){{}(<({}({}))>)}{}<>}{}<>({}<{}><>)

5

MATL , 9 byte

qtYF1)EW<

Đầu ra thật là 1. Falsy là 0hoặc đầu ra trống. (Các đầu vào duy nhất tạo ra đầu ra trống là 12phần còn lại tạo ra 0hoặc 1).

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

Giải trình

Gọi x là đầu vào. Gọi ylũy thừa lớn nhất của 2 chia x 1 và z = ( x 1) / y . Lưu ý rằng z là tự động lẻ. Khi đó x là số Proth khi và chỉ khi y > z hoặc tương đương nếu y 2 > x 1.

q    % Input x implicitly. Subtract 1
t    % Duplicate
YF   % Exponents of prime factorization of x-1
1)   % First entry: exponent of 2. Errors for x equal to 1 or 2
E    % Duplicate
W    % 2 raised to that. This is y squared
<    % Is x-1 less than y squared? Implicitly display

5

Brachylog , 28 byte

>N>0,2:N^P:K*+?,P>K:2%1,N:K=

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

Xác nhận tất cả các testcase cùng một lúc. (Sửa đổi một chút.)

Giải trình

Brachylog, là một dẫn xuất của Prolog, rất giỏi trong việc chứng minh mọi thứ.

Ở đây, chúng tôi chứng minh những điều này:

>N>0,2:N^P:K*+?,P>K:2%1,N:K=

>N>0                           input > N > 0
     2:N^P                     2^N = P
         P:K*+?                P*K+1 = input
                P>K            P > K
                  K:2%1        K%2 = 1
                        N:K=   [N:K] has a solution

5

Haskell, 55 46 byte

f x=length [x|k<-[1,3..x],n<-[1..x],k*2^n+1==x,2^n>k]>0

Chỉnh sửa: Nhờ nimi, giờ là 46 byte

f x=or[k*2^n+1==x|k<-[1,3..x],n<-[1..x],2^n>k]

4
Chào mừng bạn đến với Câu đố lập trình & Code Golf!
Dennis

Cảm ơn người đàn ông! Đã là một kẻ ẩn giấu ở đây một thời gian. Quạt lớn btw, thạch siêu mát. Ước gì tôi có thể học nhưng than ôi, tôi không thực sự hiểu
X88B88

2
Một mẹo chung: nếu bạn chỉ quan tâm đến độ dài của danh sách được tạo bởi sự hiểu biết, bạn có thể sử dụng sum[1| ... ]. Ở đây chúng ta có thể đi xa hơn và di chuyển bài kiểm tra đẳng thức ở phía trước |và kiểm tra xem có orbất kỳ trong số chúng là đúng không : f x=or[k*2^n+1==x|k<-...,n<-...,2^n>k].
nimi

Ồ Lời khuyên tuyệt vời. Tôi chắc chắn sẽ sửa đổi.
X88B88

2
Nếu bạn thích học Jelly, hãy xem wiki hoặc tham gia phòng Jelly .
Dennis

5

Chính sách ECMAScript, 48 43 41 byte

Regexes của Neil và H.PWiz (cả hương vị ECMAScript) đều đẹp theo cách riêng của họ. Có một cách khác để làm điều đó, mà theo một sự trùng hợp gọn gàng khá là 1 byte hơn Neil, và bây giờ với chơi golf gợi ý H.PWiz của (cảm ơn!), Là 1 byte hơn ít hơn H.PWiz của.

Cảnh báo: Mặc dù kích thước nhỏ của regex này, nó có chứa một spoiler chính . Tôi đặc biệt khuyên bạn nên học cách giải quyết các vấn đề toán học đơn phương trong biểu thức ECMAScript bằng cách tìm ra những hiểu biết toán học ban đầu một cách độc lập. Đó là một hành trình hấp dẫn đối với tôi và tôi không muốn làm hỏng nó cho bất kỳ ai có khả năng muốn thử nó, đặc biệt là những người quan tâm đến lý thuyết số.Xem bài đăng trước đó để biết danh sách các vấn đề được đề xuất liên quan đến spoiler để giải quyết từng vấn đề một.

Vì vậy, đừng đọc thêm nữa nếu bạn không muốn một số phép thuật regex unary tiên tiến được làm hỏng cho bạn . Nếu bạn thực sự muốn tự mình tìm ra phép thuật này, tôi khuyên bạn nên bắt đầu bằng cách giải quyết một số vấn đề trong biểu thức ECMAScript như được nêu trong bài đăng được liên kết ở trên.

Vì vậy, regex này hoạt động khá đơn giản: Nó bắt đầu bằng cách trừ đi một. Sau đó, nó tìm thấy yếu tố lẻ lớn nhất, k . Sau đó, chúng tôi chia cho k (sử dụng thuật toán phân chia được giải thích ngắn gọn trong một đoạn được gắn thẻ spoiler của bài đăng số giai thừa của tôi ). Chúng tôi lén lút xác nhận đồng thời rằng thương số kết quả lớn hơn k . Nếu phân chia khớp, chúng ta có số Proth; nếu không, chúng tôi không.

Tôi đã có thể giảm 2 byte từ regex này (43 → 41) bằng cách sử dụng một mẹo được tìm thấy bởi Grimy có thể rút ngắn phân chia trong trường hợp thương số được đảm bảo lớn hơn hoặc bằng số chia.

^x(?=(x(xx)*)\1*$)((\1x*)(?=\1\4*$)x)\3*$

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


 # Match Proth numbers in the domain ^x*$
 ^
 x                         # tail = tail - 1
 (?=(x(xx)*)\1*$)          # \1 = largest odd factor of tail
 
 # Calculate tail / \1, but require that the quotient, \3, be > \1
 # (and the quotient is implicitly a power of 2, because the divisor
 # is the largest odd factor).
 (                         # \3 = tail / \1, asserting that \3 > \1
     (\1x*)                # \4 = \3-1
     (?=\1\4*$)            # We can skip the test for divisibility by \1-1
                           # (and avoid capturing it) because we've already
                           # asserted that the quotient is larger than the
                           # divisor.
     x
 )
 \3*$
 


1
O_o wow, chỉ có 48 byte
ASCII - chỉ

Neil's giống với tôi hơn là của Dennis '
H.PWiz

4

Julia, 16 byte

!x=~-x&-~-x>x^.5

Tín dụng cho @Dennis cho câu trả lời và một số mẹo chơi golf!


Điều đó không hiệu quả. Trong Julia, &có quyền ưu tiên như *.
Dennis

1
Ô đung rôi. Đã sửa lỗi: PI thực sự nên kiểm tra mã của tôi.
Mama Fun Roll

2
Bạn có thể sử dụng -~-xthay vì (1-x). Ngoài ra, có √xthay vì x^.5, nhưng nó không lưu bất kỳ byte nào.
Dennis

4

R, 52 50 byte

x=scan()-1;n=0;while(!x%%2){x=x/2;n=n+1};2^(2*n)>x

Chương trình bắt đầu bằng cách chia N-1(được gọi ở đây Px) 2càng lâu càng tốt để tìm 2^nphần của phương trình, bỏ đi k=(N-1)/2^n, sau đó tính toán thời tiết hoặc không kkém hơn 2^n, bằng cách sử dụng thực tế rằng2^n>x/2^n <=> (2^n)²>x <=> 2^2n>x


1
Bạn có thể kéo đầu P=ở đầu và thay đổi kết thúc thành 2^n>xvà lưu như 5 hoặc 6 byte
user5957401

4

Regex (ECMAScript), 40 38 byte

-2 byte nhờ Deadcode

^x(?=((xx)+?)(\1\1)*$)(?!(\1x\2*)\4*$)

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

Phiên bản đã bình luận:

# Subtract 1 from the input N
^x

# Assert N is even.
# Capture \1 = biggest power of 2 that divides N.
# Capture \2 = 2.
(?=((xx)+?)(\1\1)*$)

# Assert no odd number > \1 divides N
(?!(\1x\2*)\4*$)

Wow, điều này là rất mát mẻ. Vì vậy, nhiều cách khác nhau để làm vấn đề này!
Deadcode

1
38 byte: ^x(?=((xx)+?)(\1\1)*$)(?!(\1x\2*)\4*$)( Dùng thử trực tuyến )
Deadcode

2

J, 10 byte

%:<<:AND-.

Dựa trên giải pháp bitwise của @Dennis .

Có một đầu vào n và trả về 1 nếu đó là số Proth khác 0.

Sử dụng

   f =: %:<<:AND-.
   f 16
0
   f 17
1
   (#~f"0) >: i. 100  NB. Filter the numbers [1, 100]
3 5 9 13 17 25 33 41 49 57 65 81 97

Giải trình

%:<<:AND-.  Input: n
        -.  Complement. Compute 1-n
   <:       Decrement. Compute n-1
     AND    Bitwise-and between 1-n and n-1
%:          Square root of n
  <         Compare sqrt(n) < ((1-n) & (n-1))

Huh. Tôi không biết về AND. mát mẻ!
Conor O'Brien

2

Võng mạc 0.8.2 , 47 byte

\d+
$*
+`(1+)\1
$+0
01
1
+`.10(0*1)$
1$1
^10*1$

Hãy thử trực tuyến! Giải thích: Cho số Prothk·2n+1, bạn có thể lấy được hai số Proth mới (2k±1)·2n+1+1. Chúng ta có thể chạy ngược lại cho đến khi chúng ta có được số Proth trong đók= =1. Điều này được thực hiện dễ dàng bằng cách chuyển đổi biểu diễn nhị phân.

\d+
$*

Chuyển đổi sang unary.

+`(1+)\1
$+0
01
1

Chuyển đổi thành nhị phân.

+`.10(0*1)$
1$1

Lặp đi lặp lại công thức tạo Proth ngược lại.

^10*1$

Phù hợp với trường hợp cơ sở của công thức tạo Proth.

Chỉnh sửa: Tôi nghĩ rằng thực sự có thể khớp số Proth trực tiếp với số đơn nguyên với một biểu thức chính quy. Điều này hiện đang đưa tôi 47 byte, nhiều hơn 7 byte so với mã Retina hiện tại của tôi để kiểm tra xem một số đơn nguyên có phải là số Proth hay không:

^.(?=(.+?)(\1\1)*$)(?=((.*)\4.)\3*$).*(?!\1)\3$

2

Regex ECMAScript, 42 byte

^x(?=(x(xx)*)\1*$)(?=(x+?)((\3\3)*$))\4\1x

Hãy thử trực tuyến! (Sử dụng võng mạc)

Tôi về cơ bản trừ đi 1, chia cho số lẻ lớn nhất có thể k, sau đó kiểm tra xem ít nhất k+1còn lại không.

Hóa ra regex của tôi rất giống với câu mà Neil đưa ra ở cuối câu trả lời của anh ấy . Tôi sử dụng x(xx)*thay vì (x*)\2x. Và tôi sử dụng một phương pháp ngắn hơn để kiểm trak < 2^n


Wow, điều này thật tuyệt vời! Hoàn thành rất tốt. Lưu ý rằng bạn có thể làm cho nó nhanh hơn một chút bằng cách thay đổi (\3\3)*)$thành(\3\3)*$)
Deadcode

Công việc tốt với mã Retina đó. Tôi không biết về $=$.=. Nó có thể được cải thiện thậm chí tốt hơn .
Deadcode

2
@Deadcode Nếu bạn định gõ đầu trang và chân trang, sau đó có một số cải tiến khác .
Neil

@Neil Trông như golf tốt, nhưng tiếc là nó có lỗi. Hãy thử số duy nhất . Họ không làm việc.
Deadcode

1
@Deadcode Xin lỗi, tôi đã không nhận ra rằng các số duy nhất là một phần của "thông số kỹ thuật".
Neil

2

Brain-Flak , 128 byte

({<{({}[()]<(([{}]())<>{})<>>)}{}>{{}(<>)}{}}<><(())>){([()]{}<(({}){})>)}{}([({}[{}(())])](<>)){({}())<>}{}{((<{}>))<>{}}{}<>{}

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

Tôi đã sử dụng một thuật toán rất khác so với giải pháp Brain-Flak cũ .

Về cơ bản, tôi chia cho 2 (làm tròn số) cho đến khi tôi đạt được số chẵn. Sau đó, tôi chỉ so sánh kết quả của phép chia cuối cùng với hai lần với sức mạnh của số lần tôi chia.

Giải trình:

({
  # (n+1)/2 to the other stack, n mod 2 to this stack
  <{({}[()]<(([{}]())<>{})<>>)}{}>
  # if 1 (n was odd) jump to the other stack and count the one
  {{}(<>)}{}
#end and push the sum -1, with a one under it
}<>[(())])
#use the one to get a power of two
{([()]{}<(({}){})>)}{}
#compare the power of two with the remainder after all the divisions
([({}[{}(())])](<>)){({}())<>}{}{((<{}>))<>{}}{}<>{}

1

Maple, 100 byte (bao gồm cả khoảng trắng)

IsProth:=proc(X)local n:=0;local x:=X-1;while x mod 2<>1 do x:=x/2;n:=n+1;end do;is(2^n>x);end proc:

Khoảng cách vừa phải để dễ đọc:

IsProth := proc( X )
    local n := 0;
    local x := X - 1;
    while x mod 2 <> 1 do
        x := x / 2;
        n := n + 1;
    end do;
    is( 2^n > x );
end proc:

Cùng một ý tưởng như một số người khác; chia X cho 2 cho đến khi X không còn chia hết cho 2, sau đó kiểm tra tiêu chí 2 ^ n> x.


1

Java 1.7, 49 43 byte

6 byte bụi khác là nhờ @charlie.

boolean g(int p){return p--<(p&-p)*(p&-p);}

Thử nó! (nhàn rỗi)

Hai cách, dài bằng nhau. Như với hầu hết các câu trả lời ở đây, các khoản tín dụng đi đến @Dennis tất nhiên cho biểu thức.

Lấy gốc của phía bên phải của biểu thức:

boolean f(int p){return(p-1&(1-p))>Math.sqrt(p);}

Áp dụng sức mạnh của hai vào phía bên trái của biểu thức:

boolean g(int p){return Math.pow(p-1&(1-p),2)>p;}

Có thể tắt một byte đơn nếu giá trị số dương được phép biểu thị 'sự thật' và giá trị âm 'giả mạo':

double g(int p){return Math.pow(p-1&(1-p),2)-p;}

Thật không may vì 'Thu hẹp chuyển đổi nguyên thủy', người ta không thể đơn giản viết điều này bằng Java và nhận được kết quả chính xác:

((p - 1 & (1 - p))^2) > p;

Và mọi nỗ lực mở rộng 'p' sẽ dẫn đến lỗi biên dịch vì các toán tử bitwise không được hỗ trợ trên phao hoặc nhân đôi :(


1
f = 47:boolean f(int p){return Math.sqrt(p--)<(p&-p);}
charlie

1
g = 43:boolean g(int p){return p--<(p&-p)*(p&-p);}
charlie

Đẹp quá Tôi biết rằng phải có một cách để loại bỏ các Math.*cuộc gọi; chỉ không thể tìm ra làm thế nào! Cảm ơn!
MH.





0

C (137 byte)

int P(int N){int x=1,n=0,k=1,e=1,P=0;for(;e;n++){for(x=1,k=1;x&&x<N;k+=2){x=2<<n;x=x>k?x*k+1:0;if(x>N&&k==1)e=0;}if(x==N)P=1;}return P;}

Chỉ đến để đọc câu trả lời sau khi tôi thử nó.

Xem xét N=k*2^n+1với các điều kiện của k<2^n( k=1,3,5..n=1,2,3..

Với n=1chúng tôi có ksẵn để thử nghiệm. Khi chúng ta tăng lên, nchúng ta sẽ có thêm một vàik's thử nghiệm như vậy:

n = 1; k = 1

n = 2; k = 1 k = 3

n = 3; k = 1 k = 3 k = 5 k = 7

...

Lặp lại qua các khả năng đó, chúng ta có thể chắc chắn N không phải là số Prouth nếu với một số đã cho n, k=1số lớn hơn N và không có phép lặp nào khác khớp.

Vì vậy, mã của tôi về cơ bản là "lực lượng vũ phu" theo cách của nó để tìm thấy N.

Sau khi đọc các câu trả lời khác và nhận ra bạn có thể tìm yếu tố N-1 với 2 để tìm n và sau đó đưa ra điều kiện k<2^n, tôi nghĩ mã của tôi có thể nhỏ hơn và hiệu quả hơn khi sử dụng phương pháp này.

Cũng đáng để thử!

Đã kiểm tra tất cả các số đã cho và một vài số "không phải Prouth". Hàm trả về 1 nếu số đó là số Prouth và 0 nếu không.


0

Javascript ES7, 16 byte

x=>x--<(-x&x)**2

Cổng câu trả lời Julia của tôi, đó là một câu trả lời của @ Dennis's Jelly.

Cảm ơn @Charlie đã lưu 2 byte!


n=x=>x-1&1-x>x**.5; n(3)mang lại cho tôi 0(thực sự nó cho tôi 0 bất kể đầu vào)
diễn ra vào

Trình duyệt nào? Nó có thể chỉ là như vậy.
Mama Fun Roll

Chrome 52. Firefox 48 đưa ra câu trả lời tương tự chon=x=>x-1&1-x>Math.pow(x,0.5); n(3)
kể từ

Ok - đó là quyền ưu tiên của nhà điều hành. Nó phải (x-1&1-x)như không có nó, quyền ưu tiên của nhà điều hành thực sự là:(x-1)&((1-x)>x**.5)
diễn ra vào

1
-1 byte: x=>x--**.5<(x&-x)hoặcx=>x**.5<(--x&-x)
charlie


0

mực , 60 byte

=p(n)
~n-=n>1
~temp x=1
-(k){n%2:{n<x}->->}
~x+=x
~n=n/2
->k

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

Dựa trên câu trả lời Maple của @ DSkoog - đây không phải là bài đầu tiên được đăng, nhưng đây là bài đầu tiên tôi thấy.

Ung dung

= is_proth(number) =

/* It's easy to check if a number is one less than a Proth number.
   We take the number and divide it by 2 until we can't.
   Once we can't, we've found the smallest possible "k".
   If we also keep track of how many times we divided, we have our corresponding "2^n"
   All we have to do then is compare those
*/

~ number -= (number > 1)            // So, we first subtract one. Except this implementation won't ever halt for 0, so we don't subtract if the input is 1 (this is fine since the desired outputs for inputs 1 and 2 are the same)
~ temp power_of_two = 1             // We declare a variable to store our "2^n"
- (check)
  {
  - number % 2:                     // Once we can't divide by 2 anymore, we've found the smallest possible "k"
    {number < power_of_two}         // At that point, we print whether it's smaller than the "2^n" we found
    ->->                            // And then we return to where we were called from
  }

  ~ number = number / 2             // We keep dividing by 2 until we can't.
  ~ power_of_two += power_of_two    // and update our "2^n" as we go
-> check

0

Mã máy x86, 15 byte

4F 89 F8 F7 D8 21 F8 0F AF C0 39 C7 19 C0 C3

Các byte này xác định một hàm lấy đối số đầu vào (một số nguyên không dấu) trong thanh EDIghi, theo quy ước gọi System V tiêu chuẩn cho các hệ thống x86 và nó trả về kết quả trong thanh EAXghi, giống như tất cả quy ước gọi x86.

Trong mnemonics lắp ráp:

4F          dec   edi            ; input -= 1
89 F8       mov   eax, edi       ; \ temp
F7 D8       neg   eax            ; |      =
21 F8       and   eax, edi       ; /        (input & -input)
0F AF C0    imul  eax, eax       ; temp *= temp
39 C7       cmp   edi, eax       ; set CF if (input < temp)
19 C0       sbb   eax, eax       ; EAX = -CF
C3          ret                  ; return with result in EAX
                                 ;  (-1 for Proth number; 0 otherwise)

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

Đây là một giải pháp khá đơn giản và có khái niệm tương tự như phiên bản C của MegaTom . Trong thực tế, bạn có thể viết điều này bằng C như sau:

unsigned IsProthNumber(unsigned input)
{
    --input;
    unsigned temp  = (input & -input);
    temp          *= temp;
    return (input < temp) ? -1 : 0;
}

nhưng mã máy ở trên được chơi tốt hơn so với những gì bạn sẽ nhận được từ trình biên dịch C, ngay cả khi nó được đặt để tối ưu hóa kích thước.

Giá trị "gian lận" duy nhất ở đây là trả về -1 dưới dạng giá trị "trung thực" và 0 là giá trị "giả". Thủ thuật này cho phép sử dụng lệnh 2 byte SBBtrái ngược với lệnh 3 byte SETB.

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.