Lonely Primes finden

21

Einsame Primzahlen (wie ich sie nenne) sind Primzahlen, bei denen ein Zahlenraster mit der Breite angegeben ist w ≥ 3und an die orthogonal oder diagonal keine anderen Primzahlen angrenzen.

Nehmen wir zum Beispiel dieses Raster, in dem w = 12(fett hervorgehobene Striche):

1   2   3   4   5   6   7   8   9   10  11  12
13  14  15  16  17  18  19  20  21  22  23...
 ...86  87  88  89  90  91  92  93  94  95  96
97  98  99  100 101 102 103 104 105 106 107 108
109 110 111 112 113 114 115 116 117 118 119 120

Es ist zu erkennen, dass nur die beiden Primzahlen 103 und 107 keine orthogonal oder diagonal benachbarten Primzahlen haben. Ich habe einen Abschnitt übersprungen, weil es dort keine einsamen Primzahlen gibt. (außer 37, eigentlich)

Ihre Aufgabe ist es, bei zwei Eingaben w ≥ 3und i ≥ 1der ersten einsamen Primzahl in einem Zahlenraster mit der Breite zu bestimmen w, wobei die einsame Primzahl größer oder gleich sein muss i. Eingaben können in jedem vernünftigen Format erfolgen (auch als Zeichenfolgen). Es ist garantiert, dass es eine einsame Primzahl für die Breite geben wird w.

Das Gitter wickelt sich nicht um.

Beispiele:

w  i   output
11 5   11
12 104 107
12 157 157
9  1   151
12 12  37

Da dies , gewinnt der kürzeste Code!

Okx
quelle
Warum ist denn w=12nicht 37eine einsame Primzahl? Keine der sie umgebenden Zahlen - {25, 26, 38, 49, 50}- sind Primzahlen.
Jonathan Frech
@ JonathanFrech Ja, ein Testfall beinhaltet das.
Okx

Antworten:

8

C (GCC) , 159 158 149 Bytes

P(n,d,b){for(d=b=1<n;n>++d;)b*=n%d>0;n=b;}F(w,i){w=P(i)&!(P(i-w)|P(i+w)|i%w>1&(P(~-i)|P(i+~w)|P(i+~-w))|i%w>0&(P(-~i)|P(-~i-w)|P(i-~w)))?i:F(w,++i);}

Probieren Sie es online!

Jonathan Frech
quelle
Sie können ein Byte speichern, indem Sie die neue Zeile überspringen. Probieren Sie es online!
Xanoetux
@ceilingcat Feiner Vorschlag, danke.
Jonathan Frech
5

JavaScript (ES6), 116 104 Bytes

Übernimmt Eingaben in der Currying-Syntax (w)(i).

w=>g=i=>!(C=(k,n=d=i+k)=>n>0?n%--d?C(k,n):d>1:1)(0)&[i,x=1,i-1].every(j=>C(x-w)&C(w+x--)|j%w<1)?i:g(i+1)

Testfälle

Kommentiert

w =>                    // main function, taking w
  g = i =>              // g = recursive function, taking i
    !(                  //
      C = (             // define C:
        k,              //   a function taking an offset k
        n = d = i + k   //   and using n and d, initialized to i + k
      ) =>              //
        n > 0 ?         //   if n is strictly positive:
          n % --d ?     //     decrement d; if d does not divide n:
            C(k, n)     //       do a recursive call
          :             //     else:
            d > 1       //       return true if d > 1 (i.e. n is composite)
        :               //   else:
          1             //     return true (n is beyond the top of the grid)
    )(0) &              // !C(0) tests whether i is prime (or equal to 1, but this is safe)
    [                   // we now need to test the adjacent cells:
      i,                //   right side: i MOD w must not be equal to 0
      x = 1,            //   middle    : always tested (1 MOD w is never equal to 0)
      i - 1             //   left side : (i - 1) MOD w must not be equal to 0
    ]                   // for each value j defined above,
    .every(j =>         // and for x = 1, 0 and -1 respectively:
      C(x - w) &        //   test whether i - w + x is composite
      C(w + x--) |      //            and i + w + x is composite
      j % w < 1         //   or j MOD w equals 0, so that the above result is ignored
    ) ?                 // if all tests pass:
      i                 //   return i
    :                   // else:
      g(i + 1)          //   try again with i + 1
Arnauld
quelle
2

Python 2 , 144 Bytes

f=lambda w,i,p=lambda n:all(n%j for j in range(2,n))*(n>1):i*(any(map(p,~-i%w*(i+~w,i-1,i+w-1)+(i-w,i+w)+i%w*(i-w+1,i+1,i-~w)))<p(i))or f(w,i+1)

Probieren Sie es online!

Argumente in der Reihenfolge: w, i.

Hier werden keine externen Module verwendet.

Python 2 + Sympy, 127 Bytes

import sympy
f=lambda w,i,p=sympy.isprime:i*(any(map(p,~-i%w*(i+~w,i-1,i+w-1)+(i-w,i+w)+i%w*(i-w+1,i+1,i-~w)))<p(i))or f(w,i+1)

Probieren Sie es online!

Kein anderer Beitrag würdig, da der einzige Unterschied darin besteht, dass sympy.isprimeanstelle einer manuell implementierten Prime-Check-Funktion verwendet wird.

Erik der Outgolfer
quelle
2

MATL , 38 Bytes

xx`@1G*:5MeZpt3Y6Z+>3LZ)ft2G<~)X<a~}2M

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Erläuterung

Der Code besteht im Wesentlichen aus einer Schleife, die das in der Challenge beschriebene Gitter bei jeder Iteration um eine Zeile vergrößert.

Nachdem das Gitter bei jeder Iteration erstellt wurde, wird die letzte Zeile entfernt (wir können nicht wissen, ob diese Primzahlen einsam sind oder nicht) und die verbleibenden Zahlen werden getestet, um festzustellen, ob mindestens eine einsame Primzahl existiert. Dies erfolgt über eine 2D-Faltung.

Wenn es eine einsame Primzahl gibt, verlassen wir die Schleife und geben die erste solche Primzahl aus. Andernfalls fahren wir mit der nächsten Iteration fort, bei der ein größeres Gitter verwendet wird.

(Der Code verwendet tatsächlich eine transponierte Version des Rasters, die durch Spalten anstelle von Zeilen vergrößert wird.)

xx        % Take two inputs (implicit): w, i. Delete them. They get copied
          % into clipboard G
`         % Do...while
  @       %   Push iteration index (1-based)
  1G      %   Push w
  *       %   Multiply
  :       %   Range from 1 to that
  5M      %   Push w again (from automatic clipboard M)
  e       %   Reshape into a matrix with w rows in column-major order
  Zp      %   Is prime? Element-wise
  t       %   Duplicate
  3Y6     %   Push neighbour mask: [1 1 1; 1 0 1; 1 1 1]
  Z+      %   2D convolution, maintaining size
  >       %   Greater than? Element-wise. Gives true for lonely primes
  3LZ)    %   Remove the last column
  f       %   Find linear indices of nonzeros
  t       %   Duplicate
  2G      %   Push i
  <~      %   Not less than?
  )       %   Use as logical index: this removes lonle primes less than i
  X<      %   Minimum. This gives either empty or a nonzero value
  a~      %   True if empty, false if nonzero. This is the loop condition.
          %   Thus the loop proceeds if no lonely prime was found
}         % Finally (execute on loop exit)
  2M      %   Push the first found lonely prime again
          % End (implicit). Display (implicit)
Luis Mendo
quelle
1

Julia 0,6, 135 Bytes

using Primes
f(w,i,p=isprime)=findfirst(j->(a=max(j-1,0);b=min(j+1,w);c=a:b;!any(p,v for v=[c;c+w;c-w]if v>0&&v!=j)&&p(j)&&j>=i),1:w*w)

TIO hat das PrimesPaket nicht. Es ist 5 Bytes kürzer , wenn ich darf alle einsamen Primzahlen zurückzukehren ( findfirstwird find). Julias Versuch, die Funktionalität zu Baseverbessern, schadet dem Golfen (kein Ziel von Julia) und Primeswurde in 0.4 aufgenommen.

Ungolfed (meistens)

function g(w,i)
    for j=i:w*w
        a,b=max(j-1,0),min(j+1,w)
        c=a:b
        !any(isprime,v for v=[c;c+w;c-w]if v>0&&v!=j)&&isprime(j)&&return j
    end
end
gggg
quelle
1

Gelee , 20 Bytes

+‘ÆRœ^ḷ,ḷ’dạ/Ṁ€ṂḊð1#

Probieren Sie es online!

Wie es funktioniert

+‘ÆRœ^ḷ,ḷ’dạ/Ṁ€ṂḊð1#  Main link. Left argument: i. Right argument: w.

                 ð    Combine the links to the left into a chain and begin a new,
                      dyadic chain with arguments i and w.
                  1#  Call the chain to the left with left argument n = i, i+1, ...
                      and right argument w until 1 of them returns a truthy value.
                      Return the match.
+                       Yield n+w.
 ‘                      Increment, yielding n+w+1.
  ÆR                    Yield all primes in [1, ..., n+w+1].
      ḷ                 Left; yield n.
    œ^                  Multiset OR; if n belongs to the prime range, remove it; if
                        it does not, append it.
       ,ḷ               Wrap the resulting array and n into a pair.
         ’              Decrement all involved integers.
          d             Divmod; map each integer k to [k/w, k%w].
           ạ/           Reduce by absolute difference, subtracting [n/w, n%w] from
                        each [k/w, k%w] and taking absolute values.
             Ṁ€         Take the maximum of each resulting pair.
                        A maximum of 0 means that n is not prime.
                        A maximum of 1 means that n has a prime neighbor.
               Ṃ        Take the minimum of the maxima.
                Ḋ       Dequeue; map the minimum m to [2, ..., m].
                        This array is non-empty/truthy iff m > 1.
Dennis
quelle
0

Sauber , 181 ... 145 Bytes

import StdEnv
@w i=hd[x+y\\y<-[0,w..],x<-[1..w]|x+y>=i&&[x+y]==[a+b\\a<-[y-w,y,y+w]|a>=0,b<-[x-1..x+1]|0<b&&b<w&&all((<)0o(rem)(a+b))[2..a+b-1]]]

Probieren Sie es online!

Ungolfed:

@ w i
    = hd [
        x+y
        \\ y <- [0, w..]
        ,  x <- [1..w]
        | x+y >= i && [x+y] == [
            a+b
            \\ a <- [y-w, y, y+w]
            | a >= 0
            ,  b <- [x-1..x+1]
            | 0 < b && b < w && all ((<) 0 o (rem) (a+b)) [2..a+b-1]
            ]
        ]
Οurous
quelle
0

Gelee ,  30  29 Bytes

Ich vermute, das ist wahrscheinlich mit einem fairen Abstand zu übertreffen

ÆPŒR+€×¥+©⁸’:⁹Ġ®ṁLÞṪFÆPS’¬ð1#

iLinks und wrechts eine dyadische Verbindung, die den einsamen Prim zurückgibt.

Probieren Sie es online!

Wie?

ÆPŒR+€×¥+©⁸’:⁹Ġ®ṁLÞṪFÆPS’¬ð1# - Link: i, w                     e.g. 37, 12
                           1# - find the 1st match starting at i and counting up of...
                          ð   - ...everything to the left as a dyadic link
                              - (n = i+0; i+1; ... on the left and w on the right):
ÆP                            -   is i prime: 1 if so, 0 if not     1
  ŒR                          -   absolute range: [-1,0,1] or [0]   [-1,0,1]
       ¥                      -   last two links as a dyad (w on the right):
      ×                       -     multiply (vectorises)           [-12,0,12]
    +€                        -     add for €ach       [[-13,-1,11],[-12,0,12],[-11,1,13]]
                              -     - i.e. the offsets if including wrapping
          ⁸                   -   chain's left argument, i
        +                     -   add                  [[24,36,48],[25,37,49],[26,38,50]]
                              -     - i.e. the adjacents if including wrapping
         ©                    -   copy to the register
           ’                  -   decrement            [[23,35,47],[24,36,48],[25,37,49]]
             ⁹                -   chain's right argument, w
            :                 -   integer division               [[1,2,3],[2,3,4],[2,3,4]]
              Ġ               -   group indices by value         [[1],[2,3]]
                              -     - for a prime at the right this would  be [[1,2],[3]]
                              -     - for a prime not at an edge it would be [[1,2,3]]
               ®              -   recall from register [[24,36,48],[25,37,49],[26,38,50]]
                ṁ             -   mould like           [[24,36,48],[[25,37,49],[26,38,50]]]
                  Þ           -   sort by:
                 L            -     length             [[24,36,48],[[25,37,49],[26,38,50]]]
                   Ṫ          -   tail                             [[25,37,49],[26,38,50]]
                              -     - i.e the adjacents now excluding wrapping
                    F         -   flatten                          [25,37,49,26,38,50]
                     ÆP       -   is prime? (vectorises)           [0,1,0,0,0,0]
                       S      -   sum                              1
                        ’     -   decrement                        0
                         ¬    -   not                              1            
Jonathan Allan
quelle
Meine Vermutung ist, dass dies wahrscheinlich mit einem fairen Vorsprung zu übertreffen ist, sind Sie sicher? Es ist keine leichte Sache für Golfsprachen.
Erik der Outgolfer
Nein, aber ich vermute, dass es (sogar) in Jelly (wenn nicht in Schale !!) ein paar Möglichkeiten gibt, meine Methode zu schonen, oder sogar einen besseren Ansatz.
Jonathan Allan
0

Java 8, 176 Bytes

w->i->{for(;;i++)if(p(i)&!(p(i-w)|p(i+w)|i%w>1&(p(i-1)|p(i+~w)|p(i+w-1))|i%w>0&(p(i+1)|p(i+1-w)|p(i-~w))))return i;}boolean p(int n){for(int i=2;i<n;n=n%i++<1?0:n);return n>1;}

Port of Jonathan Frech 'C antworten .

Probieren Sie es online aus.

Kevin Cruijssen
quelle