Znalezienie Lonely Primes

21

Liczby pojedyncze samotne (jak je nazywam) są liczbami pierwszymi, gdzie przy liczbowej siatce z szerokością w ≥ 3są liczbami pierwszych, które nie mają żadnych innych liczb pierwszych sąsiadujących z nimi prostopadle lub po przekątnej.

Na przykład, jeśli weźmiemy tę siatkę, gdzie w = 12(liczby pierwsze wyróżnione pogrubioną czcionką):

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

Widać, że tylko dwie liczby pierwsze 103 i 107 nie mają żadnych liczb pierwszych prostopadłych lub po przekątnych. Przeskoczyłem sekcję, ponieważ nie ma tam samotnych liczb pierwszych. (z wyjątkiem 37)

Twoim zadaniem jest, biorąc pod uwagę dwa dane wejściowe, w ≥ 3i i ≥ 1ustalić pierwszą samotną liczbę pierwszą w siatce liczb o szerokości w, gdzie wspomniana samotna liczba pierwsza musi być większa lub równa i. Dane wejściowe mogą być pobierane w dowolnym rozsądnym formacie (w tym przyjmowanie ich jako ciągów znaków). Jest gwarantowane, że będzie samotna pierwsza szerokość w.

Siatka się nie zawija.

Przykłady:

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

Ponieważ jest to , wygrywa najkrótszy kod!

Okx
źródło
Dlaczego w=12nie 37jest samotną liczbą pierwszą? Żadna z otaczających go liczb - {25, 26, 38, 49, 50}- nie jest liczbą pierwszą.
Jonathan Frech,
@JathanathanFrech Tak, zawiera to test.
Okx,

Odpowiedzi:

8

C (gcc) , 159 158 149 bajtów

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

Wypróbuj online!

Jonathan Frech
źródło
Możesz zapisać jeden bajt pomijając nowy wiersz. Wypróbuj online!
xanoetux
@ceilingcat Dobra sugestia, dzięki.
Jonathan Frech,
5

JavaScript (ES6), 116 104 bajtów

Pobiera dane wejściowe w składni 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)

Przypadki testowe

Skomentował

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
źródło
2

Python 2 , 144 bajty

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)

Wypróbuj online!

Argumenty w kolejności: w, i.

Nie użyto tutaj zewnętrznych modułów.

Python 2 + sympy, 127 bajtów

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)

Wypróbuj online!

Nie wart innego postu, ponieważ jedyną różnicą jest to, że używa sympy.isprimezamiast ręcznie zaimplementowanej funkcji sprawdzania liczby pierwszych.

Erik the Outgolfer
źródło
2

MATL , 38 bajtów

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

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie

Kod zasadniczo składa się z pętli, która ciągle powiększa siatkę, jak opisano w wyzwaniu, o jeden wiersz na każdej iteracji.

Po utworzeniu siatki przy każdej iteracji ostatni wiersz jest usuwany (nie wiemy, czy te liczby pierwsze są samotne, czy nie), a pozostałe liczby są testowane, aby sprawdzić, czy istnieje co najmniej jedna samotna liczba pierwsza. Odbywa się to poprzez splot 2D.

Jeśli jest jakaś samotna liczba pierwsza, wychodzimy z pętli i wypisujemy pierwszą taką liczbę pierwszą. W przeciwnym razie przejdziemy do następnej iteracji, która wypróbuje większą siatkę.

(Kod faktycznie używa transponowanej wersji siatki, która jest powiększana o kolumny zamiast o wiersze).

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
źródło
1

Julia 0.6, 135 bajtów

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 nie ma Primespakietu. Jest 5 bajtów krótszy, jeśli wolno mi zwrócić wszystkie samotne liczby pierwsze ( findfirststaje się find). Próba wyjścia Julii z funkcji Baseszkodzi golfowi (nie jest to cel Julii), Primeszostała uwzględniona w 0.4.

Niegolfowany (głównie)

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
źródło
1

Galaretka , 20 bajtów

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

Wypróbuj online!

Jak to działa

+‘Æ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
źródło
1

Perl 6 , 113 104 bajtów

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

Wypróbuj online!

Sean
źródło
0

Czysty , 181 ... 145 bajtów

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

Wypróbuj online!

Nie golfowany:

@ 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]
            ]
        ]
Obrzydliwe
źródło
0

Galaretka ,  30  29 bajtów

Domyślam się, że jest to prawdopodobnie możliwe do osiągnięcia z dość dużą marżą

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

Dyadyczne ogniwo łączące ilewą i wprawą stronę, które zwraca samotną liczbę pierwszą.

Wypróbuj online!

W jaki sposób?

Æ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
źródło
Sądzę, że jest to prawdopodobnie możliwe do osiągnięcia przez całkiem spory margines , czy jesteś pewien? Nie jest to łatwe dla golfistów.
Erik the Outgolfer
Nie, ale przypuszczam, że (nawet) w galarecie (jeśli nie łuska !!), że może być kilka sposobów na zaoszczędzenie na mojej metodzie lub nawet lepsze podejście.
Jonathan Allan
0

Java 8, 176 bajtów

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 Jonathana Frech C odpowiedzieć " .

Wypróbuj online.

Kevin Cruijssen
źródło