Encontrar solitarios primes

21

Los números primos solitarios (como los llamo) son números primos, donde, dada una cuadrícula numérica con ancho w ≥ 3, son números primos que no tienen otros números primos adyacentes a ellos de forma ortogonal o diagonal.

Por ejemplo, si tomamos esta cuadrícula donde w = 12(primos resaltados en negrita):

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

Puede ver que solo los dos números primos 103 y 107 no tienen números primos ortogonal o diagonalmente adjetivos. Me he saltado una sección porque no hay primos solitarios allí. (excepto 37, en realidad)

Su tarea es, dada dos entradas w ≥ 3y i ≥ 1, determinar el primer primo solitario en una cuadrícula de números con ancho w, donde dicho primo solitario debe ser mayor o igual que i. Las entradas pueden tomarse en cualquier formato razonable (incluso tomarlas como cadenas). Se garantiza que habrá un cebado solitario para el ancho w.

La cuadrícula no se envuelve.

Ejemplos:

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

Como se trata de , ¡el código más corto gana!

Okx
fuente
¿Por qué es de w=12no 37a un primer solo? Ninguno de los números que lo rodean {25, 26, 38, 49, 50}es primo.
Jonathan Frech
@ JonathanFrech Sí, un caso de prueba incluye eso.
Okx

Respuestas:

8

C (gcc) , 159 158 149 bytes

  • Guardado un byte gracias a xanoetux ; eliminando un personaje de nueva línea.
  • Guardado nueve bytes gracias a ceilingcat ; Golf en condición de descanso.
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);}

Pruébalo en línea!

Jonathan Frech
fuente
Puede guardar un byte omitiendo la nueva línea. Pruébalo en línea!
xanoetux el
@ceilingcat Buena sugerencia, gracias.
Jonathan Frech
5

JavaScript (ES6), 116104 bytes

Toma entrada en la sintaxis de curry (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)

Casos de prueba

Comentado

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

Pruébalo en línea!

Argumentos en orden: w, i.

No se utilizan módulos externos aquí.

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)

Pruébalo en línea!

No merece una publicación diferente, ya que la única diferencia aquí es que usa en sympy.isprimelugar de una función de verificación principal implementada manualmente.

Erik el Outgolfer
fuente
2

MATL , 38 bytes

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

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

El código consiste esencialmente en un bucle que sigue ampliando la cuadrícula como se describe en el desafío en una fila en cada iteración.

Después de crear la cuadrícula en cada iteración, se elimina la última fila (no podemos saber si esos primos son solitarios o no) y los números restantes se prueban para ver si existe al menos un primo solitario. Esto se hace a través de convolución 2D.

Si hay algún primo solitario, salimos del bucle y sacamos el primer primo. De lo contrario, procederemos con la siguiente iteración, que intentará con una cuadrícula más grande.

(El código en realidad usa una versión transpuesta de la cuadrícula, que se amplía por columnas en lugar de por filas).

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
fuente
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 no tiene el Primespaquete. Es 5 bytes más corto si se me permite devolver todos los primos solitarios (se findfirstconvierte find). El intento de Julia de mover la funcionalidad Baseestá perjudicando el golf (no es un objetivo de Julia), Primesse incluyó en 0.4.

Sin golf (en su mayoría)

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
fuente
1

Jalea , 20 bytes

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

Pruébalo en línea!

Cómo funciona

+‘Æ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
fuente
1

Perl 6 , 113104 bytes

->\w,\i{first {is-prime $_&none $_ «+«flat -w,w,(-w-1,-1,w-1)xx!($_%w==1),(1-w,1,w+1)xx!($_%%w)},i..*}

Pruébalo en línea!

Sean
fuente
0

Limpio , 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]]]

Pruébalo en línea!

Sin golf:

@ 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
fuente
0

Jalea ,  30  29 bytes

Supongo que esto es probablemente superable por un margen justo

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

Un enlace diádico que toma ia la izquierda y wa la derecha que devuelve el primo solitario.

Pruébalo en línea!

¿Cómo?

Æ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
fuente
Supongo que esto es probablemente superable por un margen justo, ¿estás seguro? No es una cosa fácil para los idiomas de golf.
Erik the Outgolfer
No, pero supongo que (incluso) en Jelly (¡si no es la cáscara!) Podría haber algunas maneras de ahorrar en mi método, o incluso un mejor enfoque.
Jonathan Allan el
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;}

Puerto de Jonathan Frech 'C respuesta .

Pruébalo en línea.

Kevin Cruijssen
fuente