Trả về số nguyên tố gần nhất


33

Thử thách

Đây là một cách đơn giản: Cho số nguyên dương lên tới 1.000.000, trả về số nguyên tố gần nhất.

Nếu số đó là số nguyên tố, thì bạn nên trả về số đó; nếu có hai số nguyên tố gần bằng số được cung cấp, trả về số thấp hơn của hai số đó.

Đầu vào ở dạng một số nguyên và đầu ra cũng phải ở dạng một số nguyên.

Tôi không quan tâm đến cách bạn nhận đầu vào (hàm, STDIN, v.v.) hoặc hiển thị đầu ra (hàm, STDOUT, v.v.), miễn là nó hoạt động.

Đây là mã golf, vì vậy các quy tắc tiêu chuẩn áp dụng chương trình có ít byte chiến thắng nhất!

Các trường hợp thử nghiệm

Input  =>  Output
------    -------
80     =>      79
100    =>     101
5      =>       5
9      =>       7
532    =>     523
1      =>       2

5
Xin chào và chào mừng đến với PPCG!. Để tránh bỏ phiếu do thiếu chất lượng, tôi khuyên bạn nên đăng nó lên hộp cát trước và sau vài ngày đăng nó ở đây
Luis felipe De jesus Munoz

Đây là một trong những kết quả đầu ra được yêu cầu trong thử thách này .
Arnauld

Liên quan rất chặt chẽ nhưng không hoàn toàn giống nhau.
Giuseppe

@Arnauld Tôi đã thấy cái đó, nhưng tôi nghĩ rằng chúng đủ khác nhau để đảm bảo một câu hỏi mới.
Nathan Dimmer

2
Xem thêm OEIS A051697 .
Tháp Eric

Câu trả lời:


9

Gaia , 3 byte

ṅD⌡

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

Khá chậm đối với đầu vào lớn, nhưng hoạt động được cung cấp đủ bộ nhớ / thời gian.

Tôi không chắc tại sao lại D⌡đẩy zmột lần nữa, nhưng nó làm cho câu trả lời ngắn gọn đáng chú ý này!

ṅ	| implicit input z: push first z prime numbers, call it P
 D⌡	| take the absolute difference between P and (implicit) z,
	| returning the smallest value in P with the minimum absolute difference

13

JavaScript (ES6), 53 byte

n=>(g=(o,d=N=n+o)=>N%--d?g(o,d):d-1?g(o<0?-o:~o):N)``

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

Đã bình luận

n => (            // n = input
  g = (           // g = recursive function taking:
    o,            //   o = offset
    d =           //   d = current divisor, initialized to N
    N = n + o     //   N = input + offset
  ) =>            //
    N % --d ?     // decrement d; if d is not a divisor of N:
      g(o, d)     //   do recursive calls until it is
    :             // else:
      d - 1 ?     //   if d is not equal to 1 (either N is composite or N = 1):
        g(        //     do a recursive call with the next offset:
          o < 0 ? //       if o is negative:
            -o    //         make it positive (e.g. -1 -> +1)
          :       //       else:
            ~o    //         use -(o + 1) (e.g. +1 -> -2)
        )         //     end of recursive call
      :           //   else (N is prime):
        N         //     stop recursion and return N
)``               // initial call to g with o = [''] (zero-ish)


7

Octave , 40 byte

@(n)p([~,k]=min(abs(n-(p=primes(2*n)))))

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

Điều này sử dụng thực tế là luôn có một nguyên tố giữa n2*n ( định lý Bertrand khoan Ch Quashev ).

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

@(n)p([~,k]=min(abs(n-(p=primes(2*n)))))

@(n)                                      % Define anonymous function with input n
                       p=primes(2*n)      % Vector of primes up to 2*n. Assign to p
                abs(n-(             ))    % Absolute difference between n and each prime
      [~,k]=min(                      )   % Index of first minimum (assign to k; not used)
    p(                                 )  % Apply that index to p



5

Ngôn ngữ Wolfram (Mathicala) , 31 byte

Nearest[Prime~Array~78499,#,1]&

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

                              & (*pure function*)
        Prime~Array~78499       (*among the (ascending) first 78499 primes*)
                            1   (*select one*)
Nearest[                 ,#, ]  (*which is nearest to the argument*)

1000003 là số nguyên tố thứ 78499. Nearestưu tiên các giá trị xuất hiện sớm hơn trong danh sách (giá trị thấp hơn).


5
Nearest[Prime@Range@#,#,1]&cho 27
Ben

5

Brachylog , 7 5 byte

;I≜-ṗ

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

Đã lưu 2 byte nhờ @DLosc.

Giải trình

;I≜      Label an unknown integer I (tries 0, then 1, then -1, then 2, etc.)
   -     Subtract I from the input
    ṗ    The result must be prime

@DLosc Chủ yếu là vì tôi ngu. Cảm ơn.
Gây tử vong

Tôi nghĩ rằng chúng tôi chỉ tiếp cận nó từ các hướng khác nhau. Bạn đã suy nghĩ về từ đầu, tôi giả sử, trong khi tôi đã suy nghĩ về việc ghép và trừ và chỉ sau đó tôi nhận ra rằng tôi cần phải làm cho nó hoạt động. :)
DLosc

4

Bình thường, 10 byte

haDQfP_TSy

Dùng thử trực tuyến tại đây hoặc xác minh tất cả các trường hợp thử nghiệm cùng một lúc tại đây .

haDQfP_TSyQ   Implicit: Q=eval(input())
              Trailing Q inferred
         yQ   2 * Q
        S     Range from 1 to the above
    f         Filter keep the elements of the above, as T, where:
     P_T        Is T prime?
  D           Order the above by...
 a Q          ... absolute difference between each element and Q
                This is a stable sort, so smaller primes will be sorted before larger ones if difference is the same
h             Take the first element of the above, implicit print

4

Thạch , 9 7 byte

ḤÆRạÞµḢ

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

Chậm cho đầu vào lớn hơn, nhưng hoạt động tốt cho phạm vi được yêu cầu. Cảm ơn @EriktheOutgolfer đã lưu 2 byte!


Này, thật thông minh! Tiết kiệm hai bằng cách thay thế _A¥bằng (sự khác biệt tuyệt đối). Oh, và thực sự có thể được .
Erik the Outgolfer

@EriktheOutgolfer cảm ơn. Chắc chắn sử dụng sẽ không luôn luôn làm việc? Điều đó có nghĩa là chỉ các số nguyên tố tối đa n + 1 sẽ được tìm thấy, trong khi gần nhất có thể là n + 2.
Nick Kennedy

Hừm, đó là một mối quan tâm.
Erik the Outgolfer

4

Python 2 , 71 byte

f=lambda n,k=1,p=1:k<n*3and min(k+n-p%k*2*n,f(n,k+1,p*k*k)-n,key=abs)+n

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

p(k-1)!2p%kabs(k-n)kk-nabsnk .

Biểu thức k+n-p%k*2*nđược thiết kế để đưa ra các k-nsố nguyên tố (trong đó p%k=1) và nếu không, giá trị "xấu" của giá trị k+nđó luôn lớn hơn về giá trị tuyệt đối và do đó không ảnh hưởng đến mức tối thiểu, do đó các số nguyên tố không được chuyển qua.



3

Gọn gàng , 43 byte

{x:(prime↦splice(]x,-1,-∞],[x,∞]))@0}

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

Giải trình

Đây là một lambda với tham số x. Điều này hoạt động bằng cách tạo ra trình tự sau:

[x - 1, x, x - 2, x + 1, x - 3, x + 2, x - 4, x + 3, ...]

Đây là kết nối hai chuỗi ]x, -1, -∞](đóng trái, mở phải) và[x, ∞] (cả mở).

Đối với x = 80, điều này trông giống như:

[79, 80, 78, 81, 77, 82, 76, 83, 75, 84, 74, 85, ...]

Sau đó, chúng tôi sử dụng f↦sđể chọn tất cả các yếu tố từ sthỏa mãn f. Trong trường hợp này, chúng tôi lọc ra tất cả các số tổng hợp, chỉ để lại các số nguyên tố. Đối với cùng x, điều này trở thành:

[79, 83, 73, 71, 89, 67, 97, 61, 59, 101, 103, 53, ...]

Sau đó, chúng tôi sử dụng (...)@0để chọn thành viên đầu tiên của chuỗi này. Vì cần phải chọn hai mức thấp hơn, nên chuỗi bắt đầu bằng x - 1được ghép trước.

Lưu ý: Chỉ một trong số xx - 1có thể là số nguyên tố, vì vậy không có vấn đề gì khi trình tự ghép nối bắt đầu bằng x - 1. Mặc dù chuỗi có thể được mở ở cả hai phía ( [x,-1,-∞]), nhưng điều này sẽ không bao gồm xhai lần trong chuỗi. Vì vậy, vì "hiệu quả", tôi đã chọn phiên bản đóng cửa trái (cũng vì tôi thích thể hiện Tidy).



3

APL (Dyalog Extended) , 20 15 byte SBCS

Hàm tiền tố ngầm lấy cảm hứng từ câu trả lời J của Galen Ivanov .

⊢(⊃⍋⍤|⍤-⊇⊢)¯2⍭⍳

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

ɩ ndices một thông qua các cuộc tranh cãi.

¯2⍭ số thứ n của điều đó

⊢(... ) áp dụng các chức năng ngầm sau đó, với lập luận ban đầu như là đối số bên trái:

 số nguyên tố

 được lập chỉ mục bởi:

   cấp tăng dần (chỉ số sẽ sắp xếp tăng dần)
   về
  | độ lớn (giá trị tuyệt đối)
   của
  - sự khác biệt

 chọn cái đầu tiên (nghĩa là cái có chênh lệch nhỏ nhất)


3

Perl 6 , 35 byte

{$_+=($*=-1)*$++until .is-prime;$_}

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

Điều này sử dụng kỹ thuật của Veitcel để tạo danh sách 0, -1, 2, -3nhưng đơn giản hóa nó rất nhiều ($*=-1)*$++bằng cách sử dụng các biến trạng thái ẩn danh có sẵn trong P6 (ban đầu tôi có -1 ** $++ * $++, nhưng khi đánh gôn thì mất quyền ưu tiên). Có một trình kiểm tra chính được tích hợp sẵn nhưng không may là untilngăn chặn giá trị được trả về tự động để có thêm một giá $_treo xung quanh.


Tôi thường sử dụng một cách tiếp cận toán tử chuỗi cho một cái gì đó như thế này, nhưng dài hơn một byte , vì vậy công việc tuyệt vời là tìm ra một phương pháp ngắn hơn
Jo King

@JoKing bắt tốt. Những điều xảy ra khi tôi chơi golf quá nhanh sau khi nhận được giải pháp làm việc. Tôi đã có một cái tương tự nhưng thiếu chết tiệt [-1] haha
user0721090601

3

C, 122 121 104 byte

p(a,i){for(i=1;++i<a;)if(a%i<1)return 0;return a>1;}c(a,b){for(b=a;;b++)if(p(--a)|p(b))return p(b)?b:a;}

Sử dụng chức năng gọi nó c()và chuyển làm đối số số; nó sẽ trả về số nguyên tố gần nhất.

Nhờ Embodiment of Ignorance cho 1 byte đã lưu một cải tiến lớn.

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


Nhưng c()nhận được hai thông số ... Ngoài ra, bạn có lẽ có thể rút ngắn while(1)tới for(;;)(chưa được kiểm tra, vì tôi không nhận được thế nào để chạy mã của bạn
Embodiment of Ignorance

@EmbodimentofIgnorance Tôi đã viết nó và kiểm tra tất cả trên một trình biên dịch c trực tuyến , tôi có thể gọi c()chỉ truyền tham số đầu tiên. Và bạn đã đúng, for(;;)tiết kiệm cho tôi một byte, chỉ còn lại 117 để có được vị trí đầu tiên :)
Lince Assassino

110 byte : #define r return p(a,i){i=1;while(++i<a)if(a%i<1)r 0;r a>1;}c(a,b){b=a;for(;;b++){if(p(--a))r a;if(p(b))r b;}}. Đây là một liên kết TIO: tio.run/ cường
Hiện thân của sự thiếu hiểu biết




2

APL (NARS), 38 ký tự, 76 byte

{⍵≤1:2⋄0π⍵:⍵⋄d←1π⍵⋄(d-⍵)≥⍵-s←¯1π⍵:s⋄d}

0π là phép thử cho số nguyên tố, ¯1π số nguyên tố trước, 1π là số nguyên tố tiếp theo; kiểm tra:

  f←{⍵≤1:2⋄0π⍵:⍵⋄d←1π⍵⋄(d-⍵)≥⍵-s←¯1π⍵:s⋄d}
  f¨80 100 5 9 532 1
79 101 5 7 523 2 


2

Perl 5 , 59 byte

$a=0;while((1x$_)=~/^.?$|^(..+?)\1+$/){$_+=(-1)**$a*($a++)}

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

/^.?$|^(..+?)\1+$/ là regex khó khăn để kiểm tra nguyên tố

(-1)**$a*($a++) tạo chuỗi 0, -1, 2, -3 ...


2

MathGolf , 10 byte

∞╒g¶áÅ-±├Þ

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

Giải trình:

            # Double the (implicit) input-integer
            # Create a list in the range [1, 2*n]
  g         # Filter so only the prime numbers remain
    áÅ       # Sort this list using the next two character:
           #  The absolute difference with the (implicit) input-integer
            # Push the first item of the list
             # (unfortunately without popping the list itself, so:)
         Þ   # Discard everything from the stack except for the top
             # (which is output implicitly as result)

@JoKing Cảm ơn! Tôi biết Max nghĩ về việc thay đổi nó, nhưng không biết anh ta thực sự đã làm. Các tài liệu vẫn nêu cái cũ.
Kevin Cruijssen

À, tôi sử dụng tệp mathgolf.txt làm tài liệu tham khảo, vì dường như nó được cập nhật hơn
Jo King

@JoKing Vâng, hôm qua anh ấy cũng nói với tôi về tập tin đó. Sẽ sử dụng nó từ bây giờ. :)
Kevin Cruijssen


2

C # (Trình biên dịch tương tác Visual C #) , 104 100 byte

n=>{int r=0,t=0,m=n;while(r!=2){n+=(n<m)?t:-t;t++;r=0;for(int i=1;i<=n;i++)if(n%i==0)r++;}return n;}

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

Giải trình:

int f(int n)
{
    int r = 0; //stores the amount of factors of "n"
    int t = 0; //increment used to cover all the integers surrounding "n"
    int m = n; //placeholder to toggle between adding or substracting "t" to "n"

    while (r != 2) //while the amount of factors found for "n" is different to 2 ("1" + itself)
    {
        n += (n < m) ? t : -t; //increment/decrement "n" by "t" (-0, -1, +2, -3, +4, -5,...)
        t++;
        r = 0;
        for (int i = 1; i <= n; i++) //foreach number between "1" and "n" increment "r" if the remainder of its division with "n" is 0 (thus being a factor)
            if (n % i == 0) r++; 
    }
    return n;
}

Console.WriteLine(f(80)); //79

2

Java 8, 88 87 byte

n->{for(int c=0,s=0,d,N=n;c!=2;s++)for(c=d=1,n+=n<N?s:-s;d<n;)if(n%++d<1)c++;return n;}

Cổng của câu trả lời C (đầu tiên) của @NaturalNumberGuy , vì vậy hãy đảm bảo nâng cao anh ấy !!
-1 byte nhờ @ OlivierGrégoire .

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

Giải trình:

n->{               // Method with integer as both parameter and return-type
  for(int c=0,     //  Counter-integer, starting at 0
          s=0,     //  Step-integer, starting at 0 as well
          d,       //  Divisor-integer, uninitialized
          N=n;     //  Copy of the input-integer
      c!=2;        //  Loop as long as the counter is not exactly 2 yet:
      s++)         //    After every iteration: increase the step-integer by 1
    for(c=d=1,     //   (Re)set both the counter and divisor to 1
        n+=n<N?    //   If the input is smaller than the input-copy:
            s      //    Increase the input by the step-integer
           :       //   Else:
            -s;    //    Decrease the input by the step-integer
        d<n;)      //   Inner loop as long as the divisor is smaller than the input
      if(n%++d     //    Increase the divisor by 1 first with `++d`
              <1)  //    And if the input is evenly divisible by the divisor:
        c++;       //     Increase the counter-integer by 1
  return n;}       //  Return the now modified input-integer as result

2

Java (JDK) , 103 byte

n->{int p=0,x=0,z=n,d;for(;p<1;p=p>0?z:0,z=z==n+x?n-++x:z+1)for(p=z/2,d=1;++d<z;)p=z%d<1?0:p;return p;}

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


Umm .. Tôi đã tạo ra một cổng câu trả lời của anh ấy .. ;) Mặc dù của bạn ngắn hơn 1 byte, vì vậy có gì đó khác biệt. EDIT: Ah, tôi có một số nguyên kết quả bên ngoài vòng lặp và bạn sửa đổi đầu vào bên trong vòng lặp, do đó byte -1 cho ;. :) Bạn có muốn tôi xóa câu trả lời của mình không? .. Hãy thoải mái sao chép lời giải thích.
Kevin Cruijssen

@KevinCruijssen Rất tiếc, quay lại!
Olivier Grégoire

Xin lỗi về điều đó (và cảm ơn vì byte -1). Tôi thích phiên bản của bạn là tốt, mặc dù. Đã được nâng cấp trước khi tôi thấy câu trả lời của NaturalNumberGuy.
Kevin Cruijssen

2

Haskell , 79 74 byte (nhờ Laikoni)

72 byte dưới dạng hàm ẩn danh ("f =" ban đầu có thể bị xóa trong trường hợp này).

f=(!)(-1);n!x|x>1,all((>0).mod x)[2..x-1]=x|y<-x+n=last(-n+1:[-n-1|n>0])!y

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


mã gốc:

f=(!)(-1);n!x|x>1&&all((>0).mod x)[2..x-1]=x|1>0=(last$(-n+1):[-n-1|n>0])!(x+n)

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

Giải trình:

f x = (-1)!x

isPrime x = x > 1 && all (\k -> x `mod` k /= 0)[2..x-1]
n!x | isPrime x = x            -- return the first prime found
    | n>0       = (-n-1)!(x+n) -- x is no prime, continue with x+n where n takes the 
    | otherwise = (-n+1)!(x+n) -- values -1,2,-3,4 .. in subsequent calls of (!)

1
Bên trong một người bảo vệ bạn có thể sử dụng ,thay vì &&. (last$ ...)có thể last(...), và bảo vệ thứ hai 1>0có thể được sử dụng cho một ràng buộc để lưu dấu ngoặc đơn, ví dụ y<-x+n.
Laikoni

Các hàm ẩn danh thường được cho phép, do đó, f=không cần phải tính toán ban đầu . Ngoài ra các dấu ngoặc đơn (-1+n)có thể được loại bỏ.
Laikoni

Cảm ơn những lời đề nghị. Tôi không biết "," và các ràng buộc được cho phép trong các chức năng bảo vệ! Nhưng tôi không thực sự thích ý tưởng về một chức năng đồng nghĩa như một câu trả lời. Nó không cảm thấy đúng theo ý kiến ​​của tôi.
Sachera

Bạn có thể tìm thấy nhiều lời khuyên hơn trong bộ sưu tập các mẹo chơi gôn ở Haskell của chúng tôi . Ngoài ra còn có Hướng dẫn về Quy tắc chơi gôn trong Haskell và phòng trò chuyện dành riêng: Of Monads and Men .
Laikoni

2

VDM-SL , 161 byte

f(i)==(lambda p:set of nat1&let z in set p be st forall m in set p&abs(m-i)>=abs(z-i)in z)({x|x in set{1,...,9**7}&forall y in set{2,...,1003}&y<>x=>x mod y<>0})

Một chương trình đầy đủ để chạy có thể trông như thế này - đáng chú ý là giới hạn của tập hợp các số nguyên tố được sử dụng có lẽ nên được thay đổi nếu bạn thực sự muốn chạy nó, vì sẽ mất nhiều thời gian để chạy với giá 1 triệu:

functions
f:nat1+>nat1
f(i)==(lambda p:set of nat1&let z in set p be st forall m in set p&abs(m-i)>=abs(z-i)in z)({x|x in set{1,...,9**7}&forall y in set{2,...,1003}&y<>x=>x mod y<>0})

Giải trình:

f(i)==                                        /* f is a function which takes a nat1 (natural number not including 0)*/
(lambda p:set of nat1                         /* define a lambda which takes a set of nat1*/
&let z in set p be st                         /* which has an element z in the set such that */
forall m in set p                             /* for every element in the set*/
&abs(m-i)                                     /* the difference between the element m and the input*/
>=abs(z-i)                                    /* is greater than or equal to the difference between the element z and the input */
in z)                                         /* and return z from the lambda */
(                                             /* apply this lambda to... */
{                                             /* a set defined by comprehension as.. */
x|                                            /* all elements x such that.. */ 
x in set{1,...,9**7}                          /* x is between 1 and 9^7 */
&forall y in set{2,...,1003}                  /* and for all values between 2 and 1003*/
&y<>x=>x mod y<>0                             /* y is not x implies x is not divisible by y*/
} 
)


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.