Alla ricerca di Primes solitari


21

I numeri primi solitari (come li chiamo io) sono numeri primi, dove data una griglia numerica con larghezza w ≥ 3, sono numeri primi che non hanno altri numeri primi adiacenti ortogonalmente o diagonalmente.

Ad esempio, se prendiamo questa griglia dove w = 12(numeri primi evidenziati in grassetto):

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

Puoi vedere che solo i due numeri primi 103 e 107 non hanno numeri primi ortogonali o diagonali adiacenti. Ho saltato una sezione perché non ci sono numeri primi solitari lì. (tranne 37, in realtà)

Il tuo compito è, dati due input w ≥ 3e i ≥ 1, determinare il primo primo solitario in una griglia numerica con larghezza w, dove detto primo solo deve essere maggiore o uguale a i. Gli input possono essere presi in qualsiasi formato ragionevole (incluso prenderli come stringhe). È garantito che ci sarà un primo solitario per la larghezza w.

La griglia non si avvolge.

Esempi:

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

Dato che si tratta di , vince il codice più corto!


Perché w=12non è 37un primo solitario? Nessuno dei numeri che lo circondano - {25, 26, 38, 49, 50}- sono primi.
Jonathan Frech,

@JonathanFrech Sì, un caso di test lo include.
Okx,

Risposte:


8

C (gcc) , 159 158 149 byte

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);}

Provalo online!


È possibile salvare un byte saltando la nuova riga. Provalo online!
Xanoetux,

@ceilingcat Ottimo suggerimento, grazie.
Jonathan Frech,

5

JavaScript (ES6), 116 104 byte

Accetta input nella sintassi del 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)

Casi test

Commentate

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

2

Python 2 , 144 byte

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)

Provalo online!

Argomenti in ordine: w, i.

Nessun modulo esterno utilizzato qui.

Python 2 + sympy, 127 byte

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)

Provalo online!

Non degno di un post diverso, poiché l'unica differenza qui è che utilizza sympy.isprimeinvece una funzione di controllo primo implementata manualmente.


2

MATL , 38 byte

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

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

Il codice è essenzialmente costituito da un ciclo che continua ad allargare la griglia come descritto nella sfida di una riga ad ogni iterazione.

Dopo aver creato la griglia ad ogni iterazione, l'ultima riga viene rimossa (non possiamo sapere se quei numeri primi sono soli o no) e i numeri rimanenti vengono testati per vedere se esiste almeno un primo solo. Questo viene fatto tramite convoluzione 2D.

Se c'è qualche primo solitario usciamo dal ciclo e produciamo il primo primo. Altrimenti procediamo con la prossima iterazione, che proverà una griglia più ampia.

(Il codice utilizza effettivamente una versione trasposta della griglia, che viene ingrandita da colonne anziché da righe.)

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)

1

Julia 0.6, 135 byte

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 non ha il Primespacchetto. È più corto di 5 byte se mi è permesso di restituire tutti i numeri primi solitari ( findfirstdiventa find). Il tentativo di Julia di spostare fuori la funzionalità Basesta danneggiando il golf (non un obiettivo di Julia), è Primesstato incluso in 0.4.

Ungolfed (principalmente)

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

1

Gelatina , 20 byte

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

Provalo online!

Come funziona

+‘Æ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.

1

Perl 6 , 113 104 byte

->\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..*}

Provalo online!


0

Pulito , 181 ... 145 byte

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

Provalo 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]
            ]
        ]

0

Gelatina ,  30  29 byte

La mia ipotesi è che questo è probabilmente battibile con un discreto margine

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

Un collegamento diadico che prende ia sinistra ea wdestra che restituisce il primo solitario.

Provalo online!

Come?

Æ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            

Suppongo che questo sia probabilmente battibile da un discreto margine, sei sicuro? Non è una cosa facile per le lingue del golf.
Erik the Outgolfer,

No, ma suppongo che (anche) in Jelly (se non buccia !!) che ci potrebbero essere alcuni modi per risparmiare sul mio metodo o persino un approccio migliore.
Jonathan Allan,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.