加素vs减素


35

我们大多数人都知道...

所有素数p>3都是形式 在此处输入图片说明

但是,在一定范围内,加数6n+1)和减数6n-1)有多少?

挑战

给定一个整数k>5,算多少primes<=kPlusPrimes多少是MinusPrimes

例子

因为k=100我们有
[5, 11, 17, 23, 29, 41, 47, 53, 59, 71, 83, 89] 12个减号

[7, 13, 19, 31, 37, 43, 61, 67, 73, 79, 97] 11个加号

因为k=149我们有
[5, 11, 17, 23, 29, 41, 47, 53, 59, 71, 83, 89, 101, 107, 113, 131, 137, 149]
18个减号

[7, 13, 19, 31, 37, 43, 61, 67, 73, 79, 97, 103, 109, 127, 139]
15个加号

规则

您的代码必须输出2个整数:一个以MinusPrimes的形式输出,一个以PlusPrimes的形式按您喜欢的任何顺序输出(请指定是哪个)。
这是:以字节为单位的最短答案胜出!

测试用例

输入 -> 输出 [ MinusPrimesPlusPrimes ]

6->[1,0]  
7->[1,1]   
86->[11,10]  
986->[86,78]  
5252->[351,344]  
100000->[4806,4784]   
4000000->[141696, 141448]

45
我不知道!:(
Stewie Griffin

13
@StewieGriffin,如果看一下模数序列,很容易理解:0%6是6的倍数,1%6无法确定,2%6是2 3%6的倍数,4%6是3 的倍数,是2的倍数,5%6无法确定。
zzzzBov

3
@zzzzBov如果我知道模数为何有序列及其对质数的含义,那将非常有帮助...我希望高中教数论...
Socratic Phoenix,2008年

@SocraticPhoenix,模量表示“除后余数”。0、6、12等在除以6后都产生0;1、7、13都产生1。由于我们正在寻找无法分解为因数的数字,因此知道一个数字可以被大于1的整数整除会告诉我们该数字不是素数。
zzzzBov

Answers:


10

05AB1E10 9字节

多亏了Erik the Outgolfer,节省了1个字节

输出为 [PlusPrimes, MinusPrimes]

LDpÏ6%5Ñ¢

在线尝试! 或作为测试套件

说明

L             # push range [1 ... input]
 DpÏ          # keep only primes
    6%        # mod each by 6
      5Ñ      # divisors of 5 [1, 5]
        ¢     # count

6

MATL,10字节

Zq6\!5lh=s

在线尝试!验证所有测试用例

说明

Zq     % Implicitly input k. Push row vector of primes up to k
6\     % Modulo 6, element-wise
!      % Transpose into a column vector
5lh    % Push row vector [5, 1]
=      % Is equal?, element-wise with broadcast
s      % Sum of each column. Implicitly display

6

Python 2,77个字节

-2个字节,归功于Neil

lambda x:[sum(all(n%j for j in range(2,n))for n in range(i,x,6))for i in 7,5]

在线尝试!

先前的解决方案,83 81 79字节

Xcoder先生,-1个字节; Halvard
Hummel,-2个字节

lambda x:map([all(n%i for i in range(2,n))*n%6for n in range(4,x)].count,[5,1])

在线尝试!
两者都输出为[MinusPrimes,PlusPrimes]





我已经做了太多的JavaScript数组解析-我忘记了Python列表通常不需要[]s。
尼尔

因此,将n除以从i到n-1的所有数字,看是否为质数,然后生成所有整数(5,11,...)和(7,13,...),然后测试是否有问题的数字在那里,并计算它们。似乎有效。;)
Yakk

5

果冻,7个字节

s6ÆPSm4

加号,然后减号。

在线尝试!

怎么运行的

s6ÆPSm4  Main link. Argument: n

s6       Split [1, ..., n] into chunks of length 6.
  ÆP     Test all integers for primality.
    S    Sum across columns.
         This counts the primes of the form 6k + c for c = 1, ..., 6.
     m4  Take every 4th element, leaving the counts for 6k + 1 and 6k + 5.

5

Mathematica,51个字节

(s=#;Mod[Prime~Array~PrimePi@s,6]~Count~#&/@{5,1})&

在线尝试!

@ngenisis打败它,节省了4个字节

Mathematica,47个字节

sPrime~Array~PrimePi@s~Mod~6~Count~#&/@{5,1}

Mod也可以是infix,如果要命名第一个参数s,则只需使用一个命名参数即可:sPrime~Array~PrimePi@s~Mod~6~Count~#&/@{5,1}
ngenisis

5

Japt15 13 11字节

输出顺序为[+,-]

õj ò6 yx ë4

测试一下


说明

整数的隐式输入U

õj

生成一个õ从1到的整数()数组,U并检查每个整数是否为质数(j),并给出一个布尔数组。

ò6

将数组划分为长度为6的子数组。

yx

转置(y)并对列求和。

ë4

获取数组的第4个元素并隐式输出它们。


原始的19 17 16 15字节

õ fj
5â £è_%6¥X

测试一下

  • 感谢奥利弗(Oliver)的启发性建议,我将月桂树分割成15个数组后再使用5的除数得到1个字节。

3

J,23个字节

1#.5 1=/6|_1 p:@i.@p:>:

在线尝试!

1#.5 1=/6|_1 p:@i.@p:>:   input: y
          _1       p:     number of primes
                     >:   less than y + 1
             p:@i.        prime range from 0 to that number
        6|                get residues modulo 6
   5 1=/                  table of values equal to 5 or 1
1#.                       sum of each (antibase 1)

3

视网膜53 51字节

.+
$*
1
$`1¶
G`1111
A`^(11+)\1+$
1{6}

*M`111
\b1\b

在线尝试!说明:

.+
$*

转换为一元。

1
$`1¶

从1计数到n

G`1111

删除小于4的数字。

A`^(11+)\1+$

删除复合数字。

1{6}

取余数取模6。

*M`111

打印剩余的3到5之间的数字。

\b1\b

打印余数为1的数字。


3

Ruby,61 60字节

(52个字节+ 8个-rprimes标志)

->n{[1,5].map{|x|(4..n).count{|i|i.prime?&&i%6==x}}}

返回形式为[加素数,减素数]的数组。

感谢GB,节省了1个字节!

在线尝试。


您的答案和我的最新消息(在Haskell中)给我启发!
jferard '17

@jferard我很高兴听到这个消息!:)
Cristian Lupascu

您可以count在不使用splat运算符的范围内使用(节省1个字节)。
GB

3

Perl 6,42个字节

通过删除无用的空间节省了1个字节...

通过重组 通话节省了2个字节map -感谢@Joshua。

由于 .round 等于, 节省了3个字节.round: 1

实际上,复杂的指数很酷,但特性上却非常昂贵。仅仅通过放弃就节省了10个字节...

{[+] map {.is-prime*($_%6-1??i!!1)},5..$_}

在线尝试!

这是具有复杂指数的版本。(我非常喜欢删除它。)新版本的工作方式完全相同,只是复杂的指数被更短的三元运算符所代替。

{[+] map {.is-prime*exp(π*($_%6-1)i/8).round},5..$_}

在线尝试!

输出是一个复数(PlusPrimes) + (MinusPrimes)i。我希望不要过多违反规则。


说明:该函数需要一个整数参数。我们迭代从5到参数((5..$_))的所有整数。对于每种方法,我们求值.is-prime(这称为on $_,即映射块的参数),将其(如果为numped True == 1, False == 0)乘以一个复杂的指数,该指数为exp(0) = 1(for $_%6 = 1)或exp(iπ/2) = i(for $_%6 = 5),最后将其四舍五入最接近的整数。将它们相加[+]得出结果。

最后:它真的很有效,所以我不确定TIO是否不会在您获得更高数字输出之前就超时(对于1e5,这在我的机器上需要26秒,并且TIO往往会更慢)。


没关系。做得好!

我想你的意思是高效?不错的方法!
乔纳森·艾伦

那是粗鲁的讽刺尝试:-)。
拉米利斯

打高尔夫球时,使用mapgrep有时会花费您几个字符的方法形式。这样可以节省2个字符:{[+] map {.is-prime*exp(π*($_%6-1)i/8).round: 1},5..$_}
约书亚

忘了在这里做,谢谢您的关注!
拉米利斯

2

其实是21个位元组

u5x`p░⌠6@%1=;`╖*ƒ⌡Ml╜

在线尝试!

首先输出PlusPrimes,然后输出MinusPrimes

说明:

u5x`p░⌠6@%1=;`╖*ƒ⌡Ml╜
u5x                    range(5, n+1)
   `p░                 primes in range
      ⌠6@%1=;`╖*ƒ⌡M    for each prime:
       6@%               mod 6
          1=             equal to 1
            ;`╖*ƒ        execute ╖ if p%6==1 (add 1 to register 0, consuming p)
                   l   length of resulting list (MinusPrimes)
                    ╜  push value in register 0 (PlusPrimes)


2

MATLAB 2017a,29字节

sum(mod(primes(k),6)'==[5,1])

说明:primes(k)获取所有素数,包括k。mod(primes(k),6)'取所有素数的模数6并进行转置,以便总和沿着正确的维数运行。==[5,1]在第一列中将所有5(减Prime)设置为1,在第二列中将所有5(减Prime)设置为1。sum()对每一列求和。

这个输出 [minusPrime, plusPrime]


2

Japt18 16字节

-2字节感谢@Oliver

õ_j ©Z%6
5â £è¥X

在线尝试!

以格式输出[PlusPrimes, MinusPrimes]


嗯...我回到办公桌前,打了一下我的高尔夫球,将其压缩到17个字节,然后看到您已经发布了此消息...不知道我是否应该发布它,因为我们两个解决方案的关键都在映射[5,1]获得计数,然后您首先到达那里。
毛茸茸的

@Shaggy IMO您的解决方案有足够的差异,可以单独保留。您使用filter和一个字符串;我使用了õ和数组的映射功能。此外,我[5,1]从另一个答案中得到了这个主意。
贾斯汀·马里纳

我会考虑一下。使用相似方法的不同语言的解决方案(即使其中一个“借用”另一种方法)也可以,但是使用相同语言的2个解决方案对我来说并不完全适合。我现在已将其编辑为替代内容。
毛茸茸的

我决定使用它,然后再剃掉另一个字节。
毛茸茸的

您可以使用来获得[1,5]
奥利弗

2

C#,202 179 174个字节

-23字节,感谢Xcoder先生

-5字节感谢Cyoce

返回长度为2的数组的函数,[MinusPrimes, PlusPrimes] 通过调用执行a(n)

int[]a(int n){int[]r={0,0};for(int i=5;i<=n;i++)if(i%2*b(i)>0)if(i%6<5)r[1]++;else++r[0];return r;}int b(int n){for(int i=3;i-2<Math.Sqrt(n);i+=2)if(n%i<1)return 0;return 1;}

在“在线试用”中正确格式化的代码:此处


您可以添加tio链接吗?
Xcoder先生17年

很抱歉打高尔夫球字节对字节,194个字节:public int[]a(int n){int[]r=new int[2];for(int i=5;i<=n;i++)if(i%2*b(i)>0)if(i%6<5)r[1]++;else++r[0];return r;}public int b(int n){for(int i=3;i<=Math.Sqrt(n)+1;i+=2)if(n%i<1)return 0;return 1;}
Xcoder先生,17年

193字节:public int[]a(int n){int[]r=new int[2];for(int i=5;i<=n;i++)if(i%2*b(i)>0)if(i%6<5)r[1]++;else++r[0];return r;}public int b(int n){for(int i=3;i-2<Math.Sqrt(n);i+=2)if(n%i<1)return 0;return 1;}
Xcoder先生17年

lmao youre喜欢这个arent您;)
MysticVagabond

1
感谢您提供的所有帮助,因为您已经发布了单独的答案并表示它是我的高尔夫,所以我将原样离开我,并继续学习下一个挑战:P
MysticVagabond

2

Haskell81 69字节

f n=(\r->sum[1|i<-[2..n],all((>0).rem i)[2..i-1],rem i 6==r])<$>[5,1]

在线尝试!

第一个解决方案是:

r!l=sum[1|i<-l,rem i 6==r]
f n|l<-[i|i<-[2..n],all((>0).rem i)[2..i-1]]=(5!l,1!l)

但是我在Ruby中阅读了w0lf的答案...


1

Pyth,15个字节

/K%R6fP_TSQ5/K1

测试套件。

Pyth,16个字节

m/%R6fP_TSQd,1 5

测试套件。


怎么样?

说明#1

/ K%R6fP_TSQ5 / K1-完整程序。

     fP_TSQ-过滤范围[1 ... input]中的质数。
  %R6-每个模块的Mod 6。
 K-将它们分配给变量K。
/ 5-计算5在K中的出现次数。
            / K1-计算K中出现1的次数。
                -隐式输出结果。

说明#2

m /%R6fP_TSQd,1 5-完整程序。

     fP_TSQ-过滤范围[1 ... input]中的质数
  %R6-每个模块的Mod 6。
            ,1 5-推送列表[1,5]
m / d-计算每个有多少。  
                 -隐式输出结果。 

备择方案:

/ K%R6fP_TSQ5 / KhZ(16字节)
K%R6fP_TSQ / K5 / K1(16字节)
m /%R6fP_TSQdj15T(16个字节)
m /%R6fP_TSQd [1 5(16字节)   
m /%R6fP_TSQdsM`15(17字节)
m /%R6.MP_ZSQd,1 5(17字节)
m /%R6.MP_ZSQdj15T(17个字节)
m /%R6.MP_ZSQd [1 5(17字节)

2
恭喜10k !!
路易斯·门多

@LuisMendo非常感谢:-)
Xcoder先生17年

1

果冻 12 11  10字节

感谢@cairdcoinheringaahing提供的聊天技巧。感谢@Dennis在聊天中节省了一个字节。

ÆR%6ċЀ1,5

在线尝试!

果冻,11字节

ÆR%6µ1,5=þS

在线尝试!

果冻,11字节

ÆR%6µċ5,ċ1$

在线尝试!


这是如何运作的?

说明#1

ÆR%6ċЀ1,5   As usual, full program.

ÆR           Get all the primes in the range [2...input].
  %6         Modulo each by 6.
       1,5   The two-element list [1, 5].
    ċЀ      Count the occurrences of each of ^ in the prime range.

说明#2

ÆR%6µ1,5=þS   As usual, full program.

ÆR            Get all the primes in the range [2...input].
  %6          Modulo each by 6.
    µ         Chain separator.
     1,5      The two-element list [1, 5].
        =     Equals?   
         þ    Outer product.     
          S   Sum.

说明#3

ÆR%6µċ5,ċ1$   As usual, full program.

ÆR            All the primes in the range [2...input].
  %6          Modulo each by 6.
    µ     $   Some helpers for the chains.
       ,      Two element list.
     ċ5       The number of 5s.
        ċ1    The number of 1s.

1

Java 8,141 140 138 106 101 100 96 94 81字节

n->{int r[]={0,0},c;for(;n-->4;r[n%6/4]+=c)for(c=n;c>1;c=c-1&~n%c>>-1);return r;}

与挑战说明相比,以相反的顺序返回具有两个值的整数数组
[plusPrime, minusPrime]

我打完39 40 42字节后,@ Xynos的C#答案端口。@Nevay的 巨大帮助又使-55字节大增

说明:

在这里尝试。(最终测试用例的4000000时间稍微超过了60秒的时间限制。)

n->{                   // Method with integer parameter and integer-array return-type
  int r[]={0,0},       //  Return integer-array, starting at [0,0]
      c;               //  Temp integer
  for(;n-->4;          //  Loop (1) as long as the input is larger than 4
                       //  and decrease `n` by 1 before every iteration
      r[n%6/4]+=c)     //    After every iteration, increase the plus or minus prime by `c`
                       //    (where `c` is either 0 or 1)
    for(c=n;           //   Reset `c` to `n`
        c>1;           //   And inner loop (2) as long as `c` is larger than 1
      c=               //    Change `c` to:
        c-1&~n%c>>-1;  //     inverting the bits of `n`,                    [~n]
                       //     modulo-`c` that result,                       [%c]
                       //     then bit-shift right that by -1,              [>>-1]
                       //     and then bitwise-AND that result with `c-1`   [c-1&]
    );                 //   End of inner loop (2)
                       //  End of loop (1) (implicit / single-line body)
  return r;            //  Return result integer-array
}                      // End of method

1
106个字节:n->{int r[]={0,0},i=4,j,c;for(;i++<n;){for(j=c=1;j*j<i;)c=i%(j+=2)<1?0:c;if(i%2*c>0)r[i%6%5]++;}return r;}
Nevay

1
101字节:n->{int r[]={0,0},i=4,j,c;for(;i++<n;r[i%6%5%2]-=-i%2*c>>-1)for(j=c=1;j*j<i;)c|=i%(j+=2)-1;return r;}
Nevay

1
96个字节:n->{int r[]={0,0},i=4,j,c;for(;i++<n;r[i%6%5%2]+=i&c)for(j=c=1;j*j++<i;)c&=-i%++j>>-1;return r;}(-1感谢您j++,++j
-Nevay

1
94个字节:n->{int r[]={0,0},i=4,j,c;for(;i++<n;r[i%6/4]+=i&c)for(j=c=1;j*j++<i;)c&=-i%++j>>-1;return r;}[plusPrime, minusPrime])。
Nevay

1
81个字节:n->{int r[]={0,0},c;for(;n-->4;r[n%6/4]+=c)for(c=n;c>1;)c=c-1&~n%c>>-1;return r;}
Nevay

1

JavaScript(ES6),83 82 80 68 66字节

事实证明,完全递归的解决方案比映射数组短得多!

输出顺序为[-,+]。在3490左右某个地方出现溢出错误。

f=(n,a=[0,0])=>n>4?f(n-1,a,(g=y=>n%--y?g(y):y<2)(n)&&++a[n%6%5]):a

试试吧

o.innerText=(

f=(n,a=[0,0])=>n>4?f(n-1,a,(g=y=>n%--y?g(y):y<2)(n)&&++a[n%6%5]):a

)(i.value=6);oninput=_=>o.innerText=i.value>5?f(+i.value):[0,0]
<input id=i min=6 type=number><pre id=o>


0

CJam,19个字节

ri){mp},6f%_5e=p1e=

该程序接收来自STDIN的输入,并通过STDOUT输出用换行符分隔的两个数字。

在线尝试!

说明

ri){mp},6f%_5e=p1e=

ri                        Read integer k
  )                       Add 1
       ,                  Filter the (implicit) array [0 1 ... k] ...
   {mp}                   ... on the function "is prime"
         f                Map over the resulting array...
          %               ... the function "modulus" ...
        6                 ... with extra parameter 6
           _              Duplicate the resulting array
             e=           Count occurrences ...
            5             ... of number 5
               p          Print with newline
                 e=       Count occurrences ...
                1         ... of number 1. Implicitly display

0

R + 数字66 60 58 40字节

-16个字节感谢Jarko Dubbeldam!随后我又打了两个字节。

cat(table(numbers::Primes(4,scan())%%6))

打印PlusPrimes MinusPrimes到标准输出;从标准输入读取。

table在其输入向量中,按值的升序对每个出现的值的列表进行制表。因此,由于只有两个值,即15(mod 6),这正是我们需要的函数,以及numbers::Primes,它返回4和之间的所有素数。

在线尝试!

基数R97 91 89 86 65字节

Jarko也在这里保存了一堆字节

function(n)table((5:n)[sapply(5:n,function(x)all(x%%2:x^.5))]%%6)

这几乎与上面的相同,除了它计算基数R中的所有素数而不是使用包,并且它通过函数输出返回而不是打印出来。您会在输出中看到它返回一个名称为1和的表5,其计数如下。

在线尝试!



(丹尼斯(Dennis)向TIO添加了数字,因此现在可以使用:))
JAD


all(x%%2:x^.5>0),任何非零已经truthy,所以all(x%%2:x^.5)也工作
JAD

@JarkoDubbeldam非常好!事实证明,因为所有值都大于4我们可以摆脱的值,>4因为我们将不再2在其中作为质数,所以改为使用40个字节。
朱塞佩


0

的JavaScript(SpiderMonkey的)151140,131个字节

n=>[...Array(n+1).keys()].splice(5).filter(a=>!/^1?$|^(11+?)\1+$/.test("1".repeat(a))).reduce((r,a)=>(a%6<2?r[1]++:r[0]++,r),[0,0])

在线尝试!

感谢粗野的人帮助解决错误和打高尔夫球。

说明:

n=>                                                   // Create a lambda, taking n
    [...Array(n+1).keys()]                            // Create a list from 0 to n+1
        .splice(5)                                    // remove first five elements
        .filter(a=>                                   // filter the list to get primes
             !/^1?$|^(11+?)\1+$/.test("1".repeat(a))) // using the famous regex here: https://stackoverflow.com/questions/2795065/how-to-determine-if-a-number-is-a-prime-with-regex 
        .reduce((r,a)=>                               // reduce the list
           (a%6<2?r[1]++:r[0]++,r),                   // by counting plus primes
           [0,0])                                     // and minus primes

1
退回17,15149(应该是18,15)。您需要将阵列的大小增加1:TIO。顺便说一句,这只是“香草” ES6,其中没有特定于SpiderMonkey的东西。另外,您可以将Stack Snippets用于JS,而不是TIO。而且,您还有很多可以删除的空间。
毛茸茸的

1
另外为您节省了几笔费用,使您的字节数减少到131个字节
毛茸茸的

@Shaggy我没有意识到您可以使用reduce那样。
Pureferret
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.