Generate strong primes

14

In number theory, a strong prime is a prime number that is greater than the arithmetic mean of the nearest prime above and below (in other words, it's closer to the following than to the preceding prime).

Given an input integer, n, where n >= 0, your task is to generate the first n strong primes. For example, the sixth, seventh, and eighth primes are 13, 17, and 19, respectively:

(13 + 19) / 2 < 17

Therefore, 17 is a strong prime.

Input

  • an integer

Output

  • if n is 0
    • program: output nothing
    • function: return an empty array
  • if n is greater than 0
    • program: output the first n strong primes, each on its own line
    • function: return an array containing the first n strong primes

Test cases

0
[]

4
[11, 17, 29, 37]

7
[11, 17, 29, 37, 41, 59, 67]

47
[11, 17, 29, 37, 41, 59, 67, 71, 79, 97, 101, 107, 127, 137, 149, 163, 179, 191, 197, 223, 227, 239, 251, 269, 277, 281, 307, 311, 331, 347, 367, 379, 397, 419, 431, 439, 457, 461, 479, 487, 499, 521, 541, 557, 569, 587, 599]

See also: Strong primes on OEIS

Zach Gates

Posted 2017-09-03T07:43:16.780

Reputation: 6 152

Question was closed 2017-09-05T13:03:05.873

output n strong primes - Any n strong primes or the first n strong primes? A few test cases/examples of corresponding inputs and outputs would a nice addition to the challenge. – Mr. Xcoder – 2017-09-03T07:52:15.863

1@Mr.Xcoder: I've updated the spec; added a link to OEIS, as well. – Zach Gates – 2017-09-03T07:55:35.313

Does it really have to be a newline as delimiter? – Titus – 2017-09-03T11:49:15.103

@Titus: Yes it does. – Zach Gates – 2017-09-03T12:02:53.443

is it an "and" or an "or" in the spec? "output and return" or "output, or return"?? – Will Ness – 2017-09-03T22:14:57.937

@WillNess: Output if a program, return if a function. – Zach Gates – 2017-09-03T22:16:17.903

@WheatWizard: No; from your own comment: "not weak is different than strong". Also, that task is to determine whether or not an input, n, is a weak prime (but it's yours, so you know that). – Zach Gates – 2017-09-03T22:24:43.450

@ZachGates Its the difference between less than and greater than. Just because not weak is not the same as strong does not mean this is not a dupe. This is a minuscule difference and definitely not a large enough one to warrant its own question. – Post Rock Garf Hunter – 2017-09-04T01:58:48.497

Answers

13

Husk, 12 11 bytes

↑§foẊ<Ẋ-tİp

Try it online!

-1 byte thanks to H.PWiz.

Explanation

↑§foẊ<Ẋ-tİp  Input is n.
         İp  The infinite list of primes.
      Ẋ-     Take pairwise differences,
   oẊ<       then pairwise comparisons.
        t    Frop the first element from İp
 §f          and filter the rest using the result of oẊ<Ẋ-.
↑            Take first n elements of this list.

Zgarb

Posted 2017-09-03T07:43:16.780

Reputation: 39 083

11 bytes, but a bit more boring – H.PWiz – 2017-09-03T12:00:46.187

6

Jelly, 14 bytes

Æp+ÆnH<ȧÆP
3Ç#

Try it online!

Explanation

Æp+ÆnH<ȧÆP  Helper link. Input: k
Æp          Prime less than k
  +         Plus
   Æn       Prime greater than k
     H      Halve
      <     Less than k?
       ȧ    Logical AND
        ÆP  Is k prime?

3Ç#  Main link. Input: n
  #  Find n matches
3Ç     Call the helper link on 3, 4, 5, ...

miles

Posted 2017-09-03T07:43:16.780

Reputation: 15 654

I discovered an alternative and thought it might be worth mentioning it: Æp+Æn<ḤȧÆP – Mr. Xcoder – 2017-09-03T08:14:48.167

6

Java 182 167 153 bytes

Second version

Thank's to Roman Gräf for saving 29 bytes!

n->{int s[]=new int[n],i=1,p=i,q=i;while(n>0)if(java.math.BigInteger.valueOf(++i).isProbablePrime(n.MAX_VALUE)){if(p>(i+q)/2)s[--n]=p;q=p;p=i;}return s;}

ungolfed

int[] strongPrimes(Integer n) {
        int[] strongPrimes = new int[n];
        int i=1;
        int p1=i; //last prime
        int p2=i; //2 primes ago
        while(n>0) if(java.math.BigInteger.valueOf(++i).isProbablePrime(n.MAX_VALUE)) { //increment i and if prime
            //System.out.println("p1:"+p1+" i:"+i+" p2:"+p2);
            if(p1>(i+p2)/2) strongPrimes[--n]=p1; //if the previous one was strong
            p2=p1;
            p1=i;           
        }       
        return strongPrimes;        
    }

General

I don't think I can get it any smaller without help. Doesn't anyone now of an other build in function to check for primes?

concerns

technically there is 2^(-2^31) chance that isProbablePrime(Integer.MAX_VALUE) returns true on a non prime but this doesn't happen for an integer.

It also outputs the numbers in reverse order but I didn't see anything about the order in which the primes should be outputted but that's an easy fix (although it could cost some bytes)

fejfo

Posted 2017-09-03T07:43:16.780

Reputation: 359

int[]s(int n){int s[]=new int[n],i=1,p=i,q=i;while(n>0)if(java.math.BigInteger.valueOf(++i).isProbablePrime(n.MAX_VALUE)){if(p>(i+q)/2)s[--n]=p;q=p;p=i;}return s;} without changing any code this should be a bit shorter – Roman Gräf – 2017-09-03T15:13:58.433

RE: your concern about writing a function: it is acceptable so long as not explicitly ruled otherwise. (I'll leave it to the Java golfers to see if you can golf it!) – Jonathan Allan – 2017-09-03T15:14:52.573

@RomanGräf thank's I'll update it apparently I forgot to remove some white-space and I din't think of defining the variables like that. But "int n" doesn't work because of "n.MAX_VALUE" – fejfo – 2017-09-03T15:27:03.720

if you want you can use a lambda n->{...} that fits into a Function<Integer,int[]> – Roman Gräf – 2017-09-03T15:29:07.040

@RomanGräf does that still count? – fejfo – 2017-09-03T15:36:13.020

As far as i know yes. i use it myself a lot. I have a look for the relevant meta post. just switch your lang to java 8 – Roman Gräf – 2017-09-03T15:37:45.563

@RomanGräf how about this: https://codegolf.meta.stackexchange.com/questions/4726/java-function-literals?

– fejfo – 2017-09-03T15:42:10.737

I had this one but it is relatively clear if you search meta for lambda

– Roman Gräf – 2017-09-03T15:43:50.100

1n.MAX_VALUE (which is equivalent to -1>>>1) can be replaced with 50 (upper bound for BigIntegers with less than 100 bits) (-9 bytes), if(p‌​>(i+q)/2) can be replaced with if(2*p>i+q)(-2 bytes). – Nevay – 2017-09-03T18:43:04.467

You can test by dividing. int a=i; for(;i%--a>0;); if a>1(... – JollyJoker – 2017-09-04T07:36:32.423

Perhaps you can manually check primes to save bytes. Here is the relevant Java Tip for primes. Not sure if this saves bytes when using BigIntegers though.

– Kevin Cruijssen – 2017-09-04T12:00:25.810

1@KevinCruijssen The code doesn't actually use the BigIntegers for anything other than the primality check. – JollyJoker – 2017-09-04T13:29:59.083

1

@JollyJoker Ah, you're right. In that case the byte-count can be lowered to 133 bytes, like this: n->{int s[]=new int[n],i=1,p=i,q=i,j,t;while(n>0){for(j=2,t=++i;j<t;t=t%j++<1?0:t);if(t>1){if(p>(i+q)/2)s[--n]=p;q=p;p=i;}}return s;}.

– Kevin Cruijssen – 2017-09-04T13:51:50.610

@KevinCrujissen 118 Try it online!

– JollyJoker – 2017-09-04T14:16:06.610

1

@JollyJoker 117 bytes (Only golfed your last if).

– Olivier Grégoire – 2017-09-04T15:07:49.287

4

Python 2, 106 103 bytes

Edit: -3 bytes thanks to @Mr.Xcoder

n=input()
a=2;b=i=3
while n:
 i+=2
 if all(i%k for k in range(3,i)):
 	if i+a<b*2:print b;n-=1
	a,b=b,i

Try it online!

Quite straight forward. Loop through all prime numbers keeping track of the two last primes. When a new prime is found, we check if the previous prime is a strong prime, and then update the two primes kept track of. This is done until n strong primes have been found.

Halvard Hummel

Posted 2017-09-03T07:43:16.780

Reputation: 3 131

2(i+a)/2<b means i+a<b*2 (105 bytes) – Mr. Xcoder – 2017-09-03T08:06:22.833

2

You can reorder them a bit: a=2;b=i=3 (103 bytes)

– Mr. Xcoder – 2017-09-03T08:09:46.527

3

Mathematica, 81 66 bytes

Select[Partition[Prime@Range[#^2],3,1],Apply[#+#3<2#2&]][[;;#,2]]&  

thanx to @Marthe172 for -15 bytes

J42161217

Posted 2017-09-03T07:43:16.780

Reputation: 15 931

1-15 bytes: Select[Partition[Prime@Range[#^2],3,1],Apply[#+#3<2#2&]][[;;#,2]]& – Lukas Lang – 2017-09-03T15:01:22.703

You could use Martin's answer here to make this way shorter.

– Post Rock Garf Hunter – 2017-09-03T22:25:02.743

4@WheatWizard you could use Martin's answers any way you like – J42161217 – 2017-09-04T00:07:01.780

3

Pyth, 25 bytes

.f&P_Z>yZ+fP_ThZefP_TUZQ3

Try it here! or Check out the test Suite!


Explanation

Quite happy with this golf given that Pyth kind of lacks prime built-ins.

.f&P_Z>yZ+fP_ThZefP_TUZQ3    Full program. Note that Q means input.

.f                     Q3    First Q inputs with truthy results, starting at 3 and counting up by 1.
          fPThZ              First prime after the current number.
               efP_TUZ       The last prime before the current number.
         +                   Sum.
      >yZ                    Is the current number doubled higher than the sum?
  &P_Z                       And is the current number prime?
                             Output implicitly.

Mr. Xcoder

Posted 2017-09-03T07:43:16.780

Reputation: 39 774

2

Actually, 17 bytes

⌠;D;⌐P@P+½@P>⌡╓♂P

Try it online!

Explanation:

⌠;D;⌐P@P+½@P>⌡╓♂P
⌠;D;⌐P@P+½@P>⌡╓    first n values (starting with k=0) where:
  D    P             (k-1)th prime
   ;⌐P@ +            plus (k+1)th prime
         ½           divided by 2
 ;        @P>        is less than kth prime
               ♂P  primes at those indices

Mego

Posted 2017-09-03T07:43:16.780

Reputation: 32 998

[tag:feature-request]: P maps on a list – Erik the Outgolfer – 2017-09-03T14:37:20.553

@EriktheOutgolfer Actually has a GitHub repo. Make an issue there. – Mego – 2017-09-03T17:17:54.547

You probably misunderstood the meaning of the comment then :p (like, "this would've been shorter if behavior like other commands existed in this one too"...probably it was a fail...) – Erik the Outgolfer – 2017-09-03T17:32:56.320

2

C++, 334 bytes, 318 with MSVC

-1 byte thanks to Mr.Xcoder -1 byte thanks to Zacharý

With the MSVC compilation, you don't need to include the cmath header yourself, it compiles without

#include<vector>
#include<cmath>
typedef std::vector<int>v;v p{2};int i(int t){int m=sqrt(t)+2,i=2;for(;i<m;++i)if(t%i<1)return 0;return 1;}void n(){int l=p.back()+1;while(!i(l))++l;p.push_back(l);}auto s(int m){if(!m)return v();n();n();v r;while(r.size()!=m){if((p[0]+p[2])/2<p[1])r.push_back(p[1]);p.erase(p.begin());n();}return r;}

tsh and Mr.Xcoder answer : 131 bytes

tsh rewrote the answer in 139 bytes ( -195 ), and Mr.Xcoder golfed it more with 131 bytes

int N,t,o,a,b,i;void n(){t=++N;for(o=2;++o<t;)if(t%o<1)n();}void s(int m,int*r){b=N=t=5;for(;i<m;)if(a=b,b=t,n(),b+b>a+t)r[i++]=b;}

Mr.Xcoder TIO Link

First version ungolfed :

#include<vector>
#include<cmath>
typedef std::vector<int> v;
v p{2};
//Tells if a number is prime or not
int i(int t) {
    int m = sqrt(t) + 2, i = 2;
    for (;i < m;++i)
        if (t%i < 1)
            return 0;
    return 1;
}
//Push back the next prime number
void n() {
    int l = p.back() + 1;
    while (!i(l))
        ++l;
    p.push_back(l);
}
//Generate a list of m strong primes
auto s(int m) {
    if (!m)
        return v();
    n();
    n();
    v r;
    while (r.size() != m) {
        if ((p[0] + p[2]) / 2 < p[1])
            r.push_back(p[1]);
        p.erase(p.begin());
        n();
    }
    return r;
}

HatsuPointerKun

Posted 2017-09-03T07:43:16.780

Reputation: 1 891

1You can save 1 byte by replacing if(t%i==0) with if(t%i<1). – Mr. Xcoder – 2017-09-03T12:49:45.687

>

  • Where are you getting sqrt from? 2. I think you can remove the space between std::vector<int> and v.
  • < – Zacharý – 2017-09-03T18:04:55.723

    @Zacharý From the vector include file, apparently. It compiles with MSVC, haven't test with GCC, though – HatsuPointerKun – 2017-09-03T18:12:27.627

    Then place a note about it being MSVC-only, since I've tested on g++, and it doesn't work due to sqrt. Also, is that byte count still correct? – Zacharý – 2017-09-03T18:14:35.527

    @Zacharý I think it's correct. I used the byte counter snippet from code golf meta to do the count

    – HatsuPointerKun – 2017-09-03T18:31:42.677

    I said that because your byte count never changed after you removed the space for some reason. – Zacharý – 2017-09-03T18:37:39.303

    @Zacharý You're right, it's cause of a whitespace added by mistake – HatsuPointerKun – 2017-09-03T18:42:33.897

    almost rewritten – tsh – 2017-09-04T06:24:46.397

    131 bytes, following @tsh's suggestions. – Mr. Xcoder – 2017-09-04T13:37:48.613

    @Mr.Xcoder A function submit should be able to reuse. initialization of i should not be ignored. – tsh – 2017-09-05T01:43:08.850

    2

    05AB1E, 19 bytes

    µNØN<ØN>Ø+;›i¼NØ}})
    

    Try it online!

    Erik the Outgolfer

    Posted 2017-09-03T07:43:16.780

    Reputation: 38 134

    1

    Haskell, 123 121 114 85 bytes

    import Data.List
    g=(`take`(tails(nubBy(((>1).).gcd)[2..])>>=(\(a:b:c:_)->[b|b-a>c-b])))
    

    (anonymous function courtesy of H.PWiz; I initially thought I must both print and then return, so had a longer code)

    (not counting the g= bit)

    Running it:

    ~> g 7
    [11,17,29,37,41,59,67]
    

    Will Ness

    Posted 2017-09-03T07:43:16.780

    Reputation: 352

    @H.PWiz thanks, on all counts! – Will Ness – 2017-09-03T22:29:16.367

    Don't need to include g=, see this

    – H.PWiz – 2017-09-03T22:33:04.317

    @H.PWiz can I just have the anonymous function by itself? Trying it with the CPP pragma, it didn't work, probably because of the import. – Will Ness – 2017-09-03T22:48:35.690

    (like this)

    – Will Ness – 2017-09-03T22:50:44.580

    You don't need the CPP bit, I was just looking for a post that explained that g= wasn't counted. – H.PWiz – 2017-09-03T23:04:27.960

    I would leave it out of your code, and if you choose to add a TIO link, put it in there. Like this

    – H.PWiz – 2017-09-03T23:07:55.817

    btw, hiding the import in the header also works for some reason. but it's probably against the rules not to count the import anyway.

    – Will Ness – 2017-09-03T23:15:18.957

    The header is just to do things like pretty printing or adding test suites. It doesn't make this 0 bytes

    – H.PWiz – 2017-09-03T23:28:27.430

    0

    Python 2 + SymPy, 118 bytes

    Not as short as the classic approach, but I think it's worth posting.

    from sympy.ntheory import*
    def f(i):
     k=3
     while i:
    	if prevprime(k)+nextprime(k)<k*2and isprime(k):i-=1;yield k
    	k+=2
    

    Try it online!

    Mr. Xcoder

    Posted 2017-09-03T07:43:16.780

    Reputation: 39 774

    0

    Axiom, 109 bytes

    h(n)==(c:=s:=3;r:=[];for i in 5..by 2|prime?(i)repeat(#r>=n=>break;p:=c;c:=s;s:=i;p+s<2*c=>(r:=cons(c,r)));r)
    

    ungolf and results

    f(n)==
       p:=c:=s:=3;r:List INT:=[]
       for i in 5.. by 2|prime?(i) repeat
          #r>=n=>break
          p:=c;c:=s;s:=i;(p+s)/2<c=>(r:=cons(c,r))
       r
    
    (4) -> f 47
       (4)
       [599, 587, 569, 557, 541, 521, 499, 487, 479, 461, 457, 439, 431, 419, 397,
        379, 367, 347, 331, 311, 307, 281, 277, 269, 251, 239, 227, 223, 197, 191,
        179, 163, 149, 137, 127, 107, 101, 97, 79, 71, 67, 59, 41, 37, 29, 17, 11]
    

    RosLuP

    Posted 2017-09-03T07:43:16.780

    Reputation: 3 036

    0

    Python 2, 86 bytes

    n=input()
    u=p=2;v=i=3
    while n:
     p*=i;i+=1
     if p*p%i:
    	if u+i<2*v:print v;n-=1
    	u,v=v,i
    

    Try it online!

    Uses Wilson's theorem for the primality test.

    miles

    Posted 2017-09-03T07:43:16.780

    Reputation: 15 654

    0

    Kotlin, 181 180 bytes

    fun f(l:Int):Array<Int>{var a=1
    var b=1
    var i=0
    var c=0
    val o=Array(l,{0})
    while(l>0){c++
    if((1..c).filter{c%it==0}.size==2){if(c-b<b-a){o[i]=b
    if(++i>=l)break}
    a=b
    b=c}}
    return o}
    

    Try it online!

    Explained

    fun f(l: Int): Array<Int> {
        var a = 1 // Lowest prime
        var b = 1 // Middle prime
        var i = 0 // Current prime index
        var c = 0 // Highest prime
        val o = Array(l, { 0 }) // Output array
        while (l > 0) {  // Functions as while true, while skipping for the 0 case
            c++ // Increment the highest prime
            if ((1..c).filter { c % it == 0 }.size == 2) { // Only if it is prime
                if (c - b < b - a) {                       // If it is strongly prime
                    o[i] = b                               // Then record it
                    if (++i >= l) break                    // If we have all the answers then stop
                }                                     
                a = b                                      // Rotate the primes
                b = c                                      // As above
            }
        }
        return o  // Return the answer
    }
    

    jrtapsell

    Posted 2017-09-03T07:43:16.780

    Reputation: 915