我是Pillai素数吗?


14

皮莱素是素数为其中存在一些正,使得+ 1 0pm p 1(m!+1)0(mod p)p1(mod m)

换言之,整数是一个素数皮拉伊如果它是一个素数,如果存在另一个正整数,使得阶乘,加上1是整除p,如果p - 1不能被整除pmm1pp1m


给定一个正整数作为输入,请确定它是否为Pillai素数。皮莱素数的顺序是OEIS A063980

例如,是Pillai素数,因为:23

  • 它是素数,只有2个因数。
  • = 18满足上述条件: 23 | 14 + 1 14不划分 22 ; 23 | 18 + 1m=14m=1823(14!+1)1422 18不分 22任。23(18!+1)1822

测试用例

真相:

23
59
83
109
139
593

虚假:

5
7
8
73
89
263
437

对于真实情况,相应的m[(23, [14, 18]), (59, [15, 40, 43]), (83, [13, 36, 69]), (109, [86]), (139, [16]), (593, [274])]


您可以遵循标准的输出格式(即真/假值),也可以具有一致的Pillai素数值和不一致的值,反之亦然

您可以使用任何编程语言进行竞争,并且可以通过任何标准方法接受输入并提供输出,同时请注意,默认情况下,这些漏洞是禁止的。这是,因此每种语言的最短提交(以字节为单位)将获胜。


输入可以是一个复合整数吗?
JungHwan Min

@JungHwanMin是的,输入可以是一个复合整数。
Xcoder先生18年

我建议一个像437这样的测试用例,它是复合的,但除以18!+1。
Nitrodon

@Nitrodon添加了该测试用例,谢谢!
Xcoder先生18年

1
@DanielIndie,您可以前往:[(23, 14), (23, 18), (59, 15), (59, 40), (59, 43), (83, 13), (83, 36), (83, 69), (109, 86), (139, 16), (593, 274)]。我也将它们添加到了挑战中。
Xcoder先生18年

Answers:


9

Python 2中115个 111 110 109字节

-6个字节,感谢Xcoder先生

lambda n:n>2and cmp(*map(all,zip(*[[n%x==1or~f(x)%n,n%x]for x in range(2,n)])))<0
f=lambda x:0**x or x*f(x-1)

在线尝试!

该功能由两个部分组成~-n%x<1or~f(x)%n>0,可验证如果n 没有满足“皮莱条件”,并n%x>0为主要验证。
之后,all被应用到两个项目,第一个项目将包含False/ 0如果有一个有效的“皮莱号”,第二个将包含True/ 1如果n是素数。
这些被传递给该情景cmp将返回-1(是有效的Pillai素数)。其他组合[[0, 0], [1, 0], [1, 1]]将返回01


2
+1,聪明的算法(及其解释)是为什么我喜欢这个SE
IanF1

8

果冻11 8字节

Ṗ!%ẹ’ḍ’E

对于Pillai素数,返回0,否则返回1

在线尝试!

怎么运行的

Ṗ!%ẹ’ḍ’E  Main link. Argument: n

Ṗ         Pop; yield [1, ..., n-1].
 !        Take the factorial of each integer.
  %       Take the factorials modulo p.
   ẹ’     Find all indices of n-1.
     ḍ’   Test n-1 for divisibility by each of these indices.
       E  Return 1 if all of the resulting Booleans are equal (all 1 means there is
          no suitable m, all 0 means n is not prime), 0 if they are different.

1
我大概也可以这样做,但是我没有设法证明m∈[1,n)
暴民埃里克(Erik the Outgolfer)'18年

4
如果m≥n,则m!n整除,所以m!+1 1(mod n)
丹尼斯


5

Brachylog,19个字节

ṗ>.ḟ+₁;?%0&-₁;.%>0∧

在线尝试!

问题的翻译很简单:

ṗ          Input is a prime
>.         And output is a number less than the input
ḟ+₁;?%0    And output's factorial + 1 mod input is 0
&-₁;.%>0   And input - 1 mod output is greater than 0
∧          No further constraints

3

J30 26字节

-4字节归功于FrownyFrog

1 e.i.((|1+!)~<1~:|)1&p:*]

在线尝试!

说明:

                        1&p:*]      checks if the number is prime and if not sets it to 0
                   1~:|             checks if p is not 1 mod m
           (|1+!)~                  m factorial plus 1 modulo n
                  <                 are both conditions met?  
       i.                           generates successive m's (a list 0..n-1)
   1 e.                             1's are at the indices of m, so if there's 1 - Pillai

1
检查模n是否小于1~:|2,以节省2个字节。
FrownyFrog

1
(]|1+!@[)只是(|1+!)~
FrownyFrog

@FrownyFrog-谢谢!我正在考虑~,这与您先前的评论相吻合。
Galen Ivanov


2

Python 2中109个 107字节

lambda p:any(~-p%m>~l(m)%p<1for m in range(2,p))*all(p%i for i in range(2,p-1))
l=lambda a:0**a or a*l(a-1)

在线尝试!


说明

l发现传入的数的阶乘,所以5输入的回报120

all(p%i for i in range(2,p-1))检查是否一个数是素数,我们忽略了0和1为我们的其他条件已经排除那些的。

最后,我们使用any(~-p%m>-~l(m)%p==0for m in range(2,p))遍历所有潜在m的方法来查看是否满足我们的需求。~-p意味着p+1。然后我们检查它是否大于-~l(m)%p(转换为(m!-1)%p,然后将其与进行比较0。基本上~-p%m必须大于0且-~l(m)%p必须为0。


资料来源


改进之处


2

正如您可能在tio链接中看到的那样,并非所有情况都通过,那是因为js无法处理大数,如果存在这种要求,请尝试实现它:)

有一个双重检查F%n>n-2&(F+1)%n<1以防止误报(但与js大数字问题相反,我们确实需要(F+1)%n<1较小的数字,但将解决方案字节数减少到60

JavaScript(Node.js)90 88 86 72 68字节

  • 感谢Arnauld减少了1个字节
f=(n,F=i=2,g=0)=>n%i?f(n,F*=++i,g|=F%n>n-2&(F+1)%n<1&~-n%i>0):i==n*g

在线尝试!


2

Brachylog,13个字节

>.ḟ+₁ḋ∋?-₁f≡ⁿ

在线尝试!

成功获得Pillai素数,并通过输出变量提供最小的m,其他任何事物均失败。由于在sundar的解决方案中,如何节省字节的很大一部分是重复计算一些相当大的数的素因式分解,因此在较大的输入上它的速度非常慢。(一旦我的笔记本电脑没有电池,我可能会在本地的Brachylog安装中运行这些情况。)

 .               The output
>                is less than the input,
       ?         the input
      ∋          is an element of
     ḋ           the prime factorization of
 .               the output's
  ḟ              factorial
   +₁            plus one,
           ≡ⁿ    and the output is not an element of
          f      the list of all factors of
       ?         the input
        -₁       minus one.

1

[Perl],45个字节

use ntheory":all";is_prime($n)&&is_pillai($n)

数论模块的谓词为内置函数(is_pillai实际上返回0或最小的m,因此也求解A063828)。底层的C和Perl代码不被采用(当然)。C代码如下所示:

UV pillai_v(UV n) {
  UV v, fac = 5040 % n;
  if (n == 0) return 0;
  for (v = 8; v < n-1 && fac != 0; v++) {
    fac = (n < HALF_WORD) ? (fac*v) % n : mulmod(fac,v,n);
    if (fac == n-1 && (n % v) != 1)
      return v;
  }
  return 0;
}

(通常用uint64_t或类似代码替换UV,然后HALF_WORD决定是否可以将mulmod优化为简单的本机操作)。

纯Perl代码类似于:

sub is_pillai {
  my $p = shift;
  return 0 if $p <= 2;
  my($pm1, $nfac) = ($p-1, 5040 % $p);
  for (my $n = 8; $n < $p; $n++) {
    $nfac = mulmod($nfac, $n, $p);
    return $n if $nfac == $pm1 && ($p % $n) != 1;
  }
  0;
}


1

私语v2,230字节

> 1
> Input
>> 1…2
>> L!
>> L+1
>> L∣2
>> L⋅R
>> 2%L
>> Each 4 3
>> Each 5 9
>> Each 6 10
>> Each 7 11 3
> {0}
>> 12∖13
>> Each 8 14
>> L≠1
>> Each 16 15
>> Each 7 17 15
>> 18∖13
>> [19]
>> 2’
>> 21⋅20
>> Output 22

在线尝试!

这将为非Pillai素数返回一个空列表,否则返回一个非空列表。

怎么运行的

Whispers专为处理实数/复数而设计,并添加了一些数组命令以方便测量,因此可以重复使用 Each来遍历生成的列表。

耳语的背景:

耳语与大多数其他语言的执行路径略有不同。Whispers并非线性地遍历每一行,而仅在条件条件下进行分支,而是从文件的最后一行开始>(从此处开始,规则稍微复杂一些,但这就是我们现在所需要的),以及数字的含义取决于行是否以>或开头>>

如果该行以开头>,例如> 1> Input,则这是一条恒定线-每次都返回相同的值。在这里,数字代表其数字形式,因此第一行将始终返回1被调用时。

>>但是,如果该行以开头,则将数字视为对其他行的引用,如果可以的话,它们类似于函数调用。例如,在该行中>> 1…2,这不会对整数12执行命令,而是对从行12返回的值执行命令。在这种情况下,这些值是整数1以及我们作为输入传递的任何整数。

对于此示例,让我们考虑输入23。请记住,由于Whispers的预处理,第二行(> Input)被转换为> 23

我们的第一个命令在第3行上>> 1…2是二进位范围,在这种情况下为123,得出{1,2,... 22,23}。接下来,我们跳到第912行

>> Each 4 3
>> Each 5 9
>> Each 6 10
>> Each 7 11 3

在这里,我们有4个连续的Each语句,每个语句都对先前的结果进行迭代,本质上将这4条命令映射到第3行的数组上:范围。前三个语句是简单的地图,用线456

>> L!
>> L+1
>> L∣2

这三个命令在整数n上产生(n!+1)∣x,其中表示阶乘表示除数x是输入。最后,第12行有一个二进位图结构。

二进地图结构获得三个整数:目标,左和右,每个索引到其它线路。在这里,我们左右滑动以生成对列表,然后通过dyadic命令(目标)减少每个对。此处,如果输入为23,则列表为{1、2,... 22、23}{0、0,... 1、0},命令为

>> L⋅R

左边的参数乘以右边的参数。这将生成一个整数数组,其乘数不能被输入整除的整数的索引为0,而原始索引则为0。我们称这个数组一个。接下来,我们通过取{0}A之间的集合差值来从A移除0

> {0}
>> 12∖13

使用我们的示例输入,将产生集合{14,18,22}。接下来,我们将输入的余数除以集合中的每个值,然后检查该余数是否不等于1

>> 2%L
>> Each 8 14
>> L≠1
>> Each 16 15

同样,我们有一个01 s 的列表,需要删除0 s并将1 s替换为原始值。在这里,我们重复上面看到的代码,但使用>> 18∖13而不是12。最后,我们将此结果集转换为列表以进行最终检查。不幸的是,我们的代码还必须拒绝满足所有这些条件的复合数字,例如437。因此,我们添加了最终检查,将最终列表乘以输入的素数。由于Python乘法在列表上的工作方式,0将其替换为空列表,而1则无效。因此,我们计算输入的素数,然后将其乘以 m将s作为输入并输出最终结果:

>> 2’
>> 21⋅20
>> Output 22

0

APL(NARS),65个字符,130个字节

{∼0π⍵:0⋄m←⎕ct⋄⎕ct←0⋄r←⍬≢a/⍨{0≠⍵∣p}¨a←k/⍨0=⍵∣1+!k←⍳p←¯1+⍵⋄⎕ct←m⋄r}

这里的23x表示23r1,因此表示分数23/1,所以其他所有表示;测试:

  f←{∼0π⍵:0⋄m←⎕ct⋄⎕ct←0⋄r←⍬≢a/⍨{0≠⍵∣p}¨a←k/⍨0=⍵∣1+!k←⍳p←¯1+⍵⋄⎕ct←m⋄r}
  f¨23x 59x 83x 109x 139x 593x
1 1 1 1 1 1 
  f¨5x 7x 73x 89x 263x 437x
0 0 0 0 0 0 

0

C#(Visual C#交互式编译器),138 + 22 = 160字节

n=>Enumerable.Range(2,n-2).All(x=>n%x>0)&Enumerable.Range(1,n).Any(x=>{BigInteger a,b=1;for(a=1;a<=x;a++)b*=a;return(b+1)%n<1&(n-1)%x>0;})

TIO尚未在其Mono版本中实现System.Numerics库,因此您可以查看结果在线尝试! 在这里

说明:

using System.Numerics; //necessary to handle large numbers created by the factorials

return 
    Enumerable.Range(2,n-2).All(x=>n%x>0)       // is prime
    &
    Enumerable.Range(1,n).Any(x=>
    {
        BigInteger a,b=1;for(a=1;a<=x;a++)b*=a; //b = a!
        return (b+1)%n<1
               &                                //the condition for PPs
               (n-1)%x>0;             
    });

0

CJam,37个字节

ri_mp\[_{_M)m!)@%!\_M)%1=!@&\}fM]);:|

11如果输入是pillai素数,则输出,否则000110

说明:

                                         e# Explanation | Stack
ri_mp\[_{_M)m!)@%!\_M)%1=!@&\}fM]);:|    e# Whole code | Example input: 593
ri                                       e# Read input as integer | 593
  _                                      e# Duplicate | 593 593
   mp                                    e# Is it prime? | 593 1
     \                                   e# Swap top two stack elements | 1 593
      [                         ]        e# Delimits an array. Any operations that
                                         e# push a value are placed into the array
       _                                 e# Duplicate | 1 593 [593]
        {                    }fM         e# A for loop from 0 to (n-1) looped through
                                         e# variable M
         _                               e# Duplicate top stack value | ...[593 593]
          M)                             e# Get M+1, as if we try M=0 we get an error
                                         e# | ...[593 593 1]
            m!                           e# Factorial | ...[593 593 1]
              )                          e# Add one | ...[593 593 2]
               @                         e# Rotate stack | ...[593 2 593]
                %                        e# Modulus | ...[593 2]
                 !                       e# Equal to 0? | ...[593 0]
                  \_                     e# Swap and duplicate | ...[0 593 593]
                    M)                   e# Push M+1 | ...[0 593 593 1]
                      %                  e# Modulus | ...[0 593 0]
                       1=!               e# Not equal to 1? | ...[0 593 1]
                          @              e# Rotate | ...[593 1 0]
                           &             e# AND | ...[593 0]
                            \            e# Swap | ...[0 593]
                             }     
                                ]
                                 );      e# Dump and discard last element
                                         e# | 1 593 [...]
                                   :|    e# Flatten array with OR | 1 1
                                         e# Implicit output

在线尝试!

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.