返回最接近的素数


33

挑战

这是一个简单的例子:给定一个最大为1,000,000的正整数,返回最接近的质数。

如果数字本身是质数,则应返回该数字;如果有两个质数均接近提供的数字,则返回两者中的较低者。

输入形式为单个整数,输出形式也应为整数。

我不在乎您如何接受输入(函数,STDIN等)或显示输出(函数,STDOUT等),只要它可以工作即可。

这是代码高尔夫,因此适用标准规则-字节最少的程序将获胜!

测试用例

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

5
嗨,欢迎来到PPCG!为避免由于质量欠佳而导致的否决表决,建议您先将其发布到沙盒中,然后
再将

这是此挑战中要求的输出之一。
Arnauld

密切相关但不完全相同。
朱塞佩

@Arnauld我看到了那个,但我认为它们足够不同,可以提出一个新的问题。
内森·迪默

2
另请参阅OEIS A051697
Eric Towers

Answers:


9

盖亚 3字节

ṅD⌡

在线尝试!

对于大输入而言,速度相当慢,但是在有足够的内存/时间的情况下可以工作。

我不确定为什么要再次D⌡隐式推送z,但这使答案非常短!

ṅ	| 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个字节

n=>(g=(o,d=N=n+o)=>N%--d?g(o,d):d-1?g(o<0?-o:~o):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

八度,40字节

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

在线尝试!

这利用了一个事实,即n和之间始终存在质数2*n贝特朗–切比雪夫定理)。

怎么运行的

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

6

Japt,5个字节

_j}cU

尝试运行所有测试用例

_j}cU     :Implicit input of integer U
_         :Function taking an integer as an argument
 j        :  Test if integer is prime
  }       :End function
   cU     :Return the first integer in [U,U-1,U+1,U-2,...] that returns true


5

Wolfram语言(Mathematica),31个字节

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

在线尝试!

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

1000003是第78499个素数。Nearest优先考虑列表中较早出现的值(较低的值)。


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

5

Brachylog7 5字节

;I≜-ṗ

在线尝试!

@DLosc节省了2个字节。

说明

;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主要是因为我很愚蠢。谢谢。
致命

我认为我们只是从不同的方向进行研究。我想,您从一开始就在考虑,而我在考虑配对和减法,直到后来才意识到我需要使它起作用。:)
DLosc

4

Pyth,10个字节

haDQfP_TSy

在此处在线尝试,或在此处一次验证所有测试用例。

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

果冻9 7个字节

ḤÆRạÞµḢ

在线尝试!

对于较大的输入,速度较慢,但​​在要求的范围内可以正常工作。感谢@EriktheOutgolfer节省了2个字节!


嘿,那很聪明!_A¥(绝对差)替换以节省两个。哦,真的可以
暴民埃里克

@EriktheOutgolfer谢谢。当然使用不会总是有效吗?这意味着只会找到最多n + 1个素数,而最接近的可能是n + 2。
尼克·肯尼迪

嗯,这是一个问题。
暴民埃里克

4

Python 2 2,71个字节

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

在线尝试!

pķ-1个2p%kabs(k-n)kk-nabsnk

该表达式k+n-p%k*2*n旨在提供质k-n数(where p%k=1),否则,其“坏”值的k+n绝对值始终会更大,因此不会影响最小值,因此会传递非质数。



3

整洁,43字节

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

在线尝试!

说明

这是一个带参数的lambda x。这通过创建以下序列来起作用:

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

这将两个序列]x, -1, -∞](左关闭,右打开)和[x, ∞](两个打开)。

对于x = 80,它看起来像:

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

然后,我们使用 f↦ss满足条件中选择所有元素f。在这种情况下,我们将滤除所有合成数字,仅保留质数。对于相同的x,这变成:

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

然后,我们使用(...)@0选择该序列的第一个成员。由于需要选择两者中的较低者,因此首先x - 1拼接以开头的序列。

注意:只有一个x,并x - 1可以通过优质,所以它是好的,该拼接序列开头x - 1。虽然序列可能在两侧都是开放的([x,-1,-∞]),不必包含x两次。因此,出于“效率”的考虑,我选择了封闭式版本(也是因为我想炫耀Tidy)。



3

APL(Dyalog扩展)20 15 字节SBCS

隐式前缀函数受Galen Ivanov的J answer的启发。

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

在线尝试!

ɩ ndices一个通过论证。

¯2⍭ 第n个素数

⊢() 对此应用以下默认函数,原始参数为左参数:

 素数

 索引依据:

   升级(指数这将升序排列)
   的
  | 幅度(绝对值)
   的
  - 差异

 选择第一个(即差异最小的那个)


3

Perl 6、35个字节

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

在线尝试!

这使用了Veitcel的技术生成列表,0, -1, 2, -3但大大简化了($*=-1)*$++使用P6中可用的匿名状态变量的过程(我最初有-1 ** $++ * $++,但是打高尔夫球时,负数失去优先级)。有一个内置的素数检查器,但不幸的是,它until阻止了自动返回的值,因此还有一个额外的问题$_


我通常会使用一个序列操作方法是这样的,但就出来一个字节长,这么好的工作,找到一个更短的方法
乔金

@JoKing很好。在找到可行的解决方案后,我打高尔夫球太快会发生的事情。我有一个类似的人,但是该死的缺乏[-1]哈哈
user0721090601

3

C,122 121 104字节

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

使用它调用函数c()并传递数字作为参数;它应该返回最接近的素数。

多亏了无知的体现为1个字节节省了很大的改进。

在线尝试!


但是c()接收两个参数...另外,您可能可以将缩短while(1)for(;;)((未测试,因为我没有得到如何运行您的代码的信息
Ignorance的体现,

@EmbodimentofIgnorance我在在线c编译器上编写并测试了所有代码,可以调用c()仅传递第一个参数。而且您是对的,为for(;;)我节省了一个字节,仅剩117个位居第一:)
Lince Assassino

110个字节:#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;}}。这里是一个TIO链接:tio.run/...
无知的实施方案




2

APL(NARS),38个字符,76个字节

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

0π是素数的检验,1π是上一个素数,1π是下一个素数;测试:

  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个字节

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

在线尝试!

/^.?$|^(..+?)\1+$/ 检查棘手的正则表达式很棘手

(-1)**$a*($a++) 生成序列0,-1,2,-3 ...


2

MathGolf,10 个字节

∞╒g¶áÅ-±├Þ

在线尝试。

说明:

            # 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谢谢!我知道马克斯想改变它,但不知道他确实做了。该文档仍然指出旧的。
凯文·克鲁伊森

啊,我用的是mathgolf.txt文件作为参考,因为它似乎更是最新的
乔金

@JoKing是的,他昨天也告诉我了该文件。从现在开始将使用它。:)
凯文·克鲁伊森


2

C#(Visual C#交互式编译器)104100字节

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

在线尝试!

说明:

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

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

@NaturalNumberGuy(第一个)C答案的端口,所以请确保支持他!!
-1个字节感谢@OlivierGrégoire

在线尝试。

说明:

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

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

在线尝试!


嗯.. 我已经创建了他的答案的端口.. ;)尽管您的答案短了1个字节,所以有些不同。编辑:啊,我在循环外有一个结果整数,并且您在循环内修改了输入,因此是-1字节;。:)您要我删除答案吗?..随时复制说明。
凯文·克鲁伊森

@KevinCruijssen糟糕,已回滚!
OlivierGrégoire

抱歉(感谢-1个字节)。不过,我也喜欢您的版本。在我看到NaturalNumberGuy的答案之前已经投票了。
凯文·克鲁伊森

2

Haskell79 74字节(感谢Laikoni)

72个字节作为匿名函数(在这种情况下,可以删除开头的“ f =“)。

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

在线尝试!


原始代码:

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)

在线尝试!

说明:

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
在警卫队内,您可以使用,代替&&(last$ ...)可以使用last(...),并且第二个后卫1>0可用于绑定以保存括号,例如y<-x+n
Laikoni

通常允许使用匿名函数,因此f=不需要对初始数进行计数。也(-1+n)可以删除括号内的内容。
Laikoni

感谢您的建议。我不知道“,”,并且在功能卫士中允许绑定!但是我真的不喜欢匿名函数作为答案的想法。我认为这不对。
萨赫拉

您可以在我们的Haskell高尔夫技巧大全中找到更多技巧。在Haskell和专门的聊天室中也有《高尔夫规则指南》《单子和男人》
Laikoni

2

VDM-SL,161字节

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

一个完整的程序可能看起来像这样-值得注意的是,如果您实际上要运行此程序,则应该更改所使用的素数集的界限,因为要花费一百万时间才能花很长时间:

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

说明:

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*/
} 
)


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.