Przegrody Goldbach

18

Hipoteza Goldbacha stwierdza, że ​​każdą liczbę parzystą większą niż dwa można wyrazić jako sumę dwóch liczb pierwszych. Na przykład,

4 = 2 + 2
6 = 3 + 3
8 = 5 + 3

Gdy jednak dojdziemy do 10, dzieje się coś ciekawego. Nie tylko 10 można zapisać jako

5 + 5

ale można to również zapisać jako

7 + 3

Ponieważ 10 można wyrazić jako sumę dwóch liczb pierwszych na dwa sposoby , mówimy, że „partycja Goldbacha” wynosi 10 2. Lub bardziej ogólnie

Podział liczbowy Goldbacha to całkowita liczba różnych sposobów pisania n = p + qgdzie pi qsą liczbami pierwszymi ip >= q

Twoim wyzwaniem jest napisanie programu lub funkcji, która znajdzie partycję Goldbacha liczby. Obecnie technicznie termin „partycja Goldbacha” jest używany tylko w odniesieniu do liczb parzystych. Ponieważ jednak nieparzysta liczba całkowita p + 2 może być również wyrażona jako suma dwóch liczb pierwszych, jeśli p> 2 jest liczbą pierwszą, rozszerzymy ją na wszystkie liczby całkowite dodatnie ( A061358 ).

Możesz bezpiecznie założyć, że dane wejściowe będą zawsze dodatnimi liczbami całkowitymi i możesz pobierać dane wejściowe i wyjściowe dowolną z naszych domyślnych dozwolonych metod , na przykład argumentów funkcji i zwracanej wartości, STDIN i STDOUT, odczytywanie i zapisywanie do pliku itp.

Podziały Goldbach dodatnich liczb całkowitych do 100 to:

0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 0, 1, 1, 2, 1, 2, 0, 2, 1, 2, 1, 3, 0, 3, 1,
3, 0, 2, 0, 3, 1, 2, 1, 4, 0, 4, 0, 2, 1, 3, 0, 4, 1, 3, 1, 4, 0, 5, 1, 4,
0, 3, 0, 5, 1, 3, 0, 4, 0, 6, 1, 3, 1, 5, 0, 6, 0, 2, 1, 5, 0, 6, 1, 5, 1,
5, 0, 7, 0, 4, 1, 5, 0, 8, 1, 5, 0, 4, 0, 9, 1, 4, 0, 5, 0, 7, 0, 3, 1, 6

Jak zwykle obowiązują standardowe luki i wygrywa najkrótsza odpowiedź w bajtach!

DJMcMayhem
źródło
1
Zawsze masz takie fajne wyzwania :-)
Luis Mendo

Odpowiedzi:

6

Galaretka , 8 bajtów

_ÆRÆPSHĊ

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

Jak to działa

_ÆRÆPSHĊ  Main link. Argument: n (positive integer)

 ÆR       Prime range; yield [2, 3, 5, ..., n].
_         Subtract all primes in this range from n.
   ÆP     Compute the primality of the resulting differences.
          This returns 1 for each prime p such that n - p is also prime.
     S    Compute the sum of the resulting Booleans.
      H   Divide it by 2, since [p, n - p] and [n - p, p] have both been counted.
       Ċ  Ceil; round the resulting quotient up (needed if n = 2p).
Dennis
źródło
O wiele lepiej: D
Jonathan Allan
5

Python 2, 76 bajtów

g=lambda n,k=2:n/k/2and all(x%i for x in[k,n-k]for i in range(2,x))+g(n,k+1)

Rekurencyjnie indeksuje się od k=2celu n/2, sumując wartości gdzie zarówno ki n-ksą głównymi. Byłoby miło, aby liczyć nna dół w tym samym czasie, zamiast, ale to nie ma wątpliwości, że k=0i k=1są fałszywie zwanego prime:

g=lambda n,k=0:n/k and all(x%i for x in[k,n]for i in range(2,x))+g(n-1,k+1)

Czek pierwszości jest trial-podział, skrócona sprawdzając zarówno ki n-krazem. Stwierdziłem, że jest to krótsze niż użycie generatora twierdzenia Wilsona (79 bajtów):

f=lambda n,k=1,P=1,l=[]:n/k and P%k*(n-k in l+P%k*[k])+f(n,k+1,P*k*k,l+P%k*[k])

Ideą tego jest utrzymanie listy wszystkich liczb pierwszych w dolnej połowie, aby były sprawdzane, zanim dotrzemy do górnej połowy, ale w punkcie środkowym k=n/2nie mieliśmy czasu, aby dodać n-kdo listy out, kiedy dojdziemy do k. Pomija to wersja iteracyjna, ale ma 82 bajty:

n=input()
s=P=k=1;l=[]
while k<n:l+=P%k*[k];s+=P%k*(n-k in l);P*=k*k;k+=1
print~-s
xnor
źródło
5

MATL , 8 bajtów

tZq&+=Rz

Wypróbuj online!

Wyjaśnienie

Rozważ dane wejściowe 8jako przykład

      % Take input implicitly
t     % Duplicate
      % STACK: 8, 8
Zq    % All primes up to that number
      % STACK: 8, [2 3 5 7]
&+    % Matrix with all pairwise additions
      % STACK: 8, [4  5  7  9
                   5  6  8 10
                   7  8 10 12
                   9 10 12 14]
=     % True for entries that equal the input
      % STACK: [0 0 0 0
                0 0 1 0
                0 1 0 0
                0 0 0 0]
R     % Extract upper triangular part (including diagonal). 
      % This removes pairs that are equal up to order
      % STACK: [0 0 0 0
                0 0 1 0
                0 0 0 0
                0 0 0 0]
z     % Number of nonzero entries
      % STACK: 1
      % Display implicitly

Interesujące jest obserwowanie wykresu sekwencji przy użyciu nieco zmodyfikowanej wersji kodu:

:"@       % Input n implicitly. For each k from 1 to n, push k
tZq&+=Rz  % Same code as above. Pushes the result for each k
]v'.'&XG  % End. Concatenate all results into a vector. Plot as dots

Dla danych wejściowych 10000wynikiem jest

wprowadź opis zdjęcia tutaj

Możesz spróbować w MATL Online (Odśwież stronę, jeśli przycisk „Uruchom” nie zmieni się na „Zabij” po naciśnięciu). Wytworzenie wykresu na wejście zajmuje kilka około 25 sekund 3000; przekroczą limit czasu nakładów powyżej kilku tysięcy.

Luis Mendo
źródło
1
Ta Upper triangular partsztuczka jest naprawdę fajna!
DJMcMayhem
3

JavaScript (ES6), 77 73 70 bajtów

Zaoszczędź 3 bajty dzięki @Arnauld

f=(n,x=n)=>--x<2||n%x&&f(n,x)
g=(a,b=a>>1)=>b>1?f(b)*f(a-b)+g(a,b-1):0

fjest funkcją testu pierwszeństwa; odpowiednią funkcją jest g.

fdziała poprzez rekurencyjne odliczanie od n-1 ; przepływ kontrolny na każdym etapie wygląda następująco:

  • x<2||Jeśli x <2 , liczba jest liczbą pierwszą; zwrot 1 .
  • n%x&&W przeciwnym razie, jeśli n mod x = 0 , liczba nie jest liczbą pierwszą; powrócić n%x.
  • f(n,x-1)W przeciwnym razie liczba może być liczbą pierwszą; zmniejsz x i spróbuj ponownie.

gdziała w podobny sposób, choć z niewielkim przepływem kontroli. Działa poprzez pomnożenie f (b) przez f (ab) dla każdej liczby całkowitej b w zakresie [2, piętro (a / 2)] , a następnie zsumowanie wyników. To daje nam liczbę par, które sumują się do miejsca, w którym obie liczby w parze są liczbą pierwszą, co jest dokładnie tym, czego chcemy.

ETHprodukcje
źródło
Ponieważ ajest pozytywny, b=a>>1powinien oszczędzić bajt.
Arnauld
@Arnauld Thanks! Powinienem był pamiętać >>operatora ...
ETHproductions
Czy możesz to zrobić w odniesieniu do funkcji testu pierwszeństwa f=(n,x=n)=>--x<2||n%x&&f(n,x)?
Arnauld
@Arnauld To genialne, dzięki :)
ETHproductions
2

05AB1E , 10 8 bajtów

Niezwykle nieefektywny.

D!f-pO;î

Wypróbuj online! lub Wypróbuj mniej wydajny sposób generowania liczb pierwszych

Wyjaśnienie

n = 10 użyty jako przykład.

D          # duplicate
           # STACK: 10, 10 
 !         # factorial
           # STACK: 10, 3628800
  f        # unique prime factors
           # STACK: 10, [2,3,5,7]
   -       # subtract
           # STACK: [8,7,5,3]
    p      # is prime
           # STACK: [0,1,1,1]
     O     # sum
           # STACK: 3
      ;    # divide by 2
           # STACK: 1.5
       î   # round up
           # STACK: 2
           # implicit output
Emigna
źródło
Nie możesz üzamiast tego użyć ? Jak D!fü+r¢?
Magic Octopus Urn
1
@carusocomputing: Nie wiem, jak by to działało. Na przykład, n=10który byłby policzony (10, [5,8,12]), który wynosi 0 zamiast 2. üstosuje się tylko między każdą parą elementów. Wpadło mi to na pomysł ã, ale niestety okazało się, że 1 bajt dłużej.
Emigna,
2

GAP , 57 bajtów

n->Number([2..QuoInt(n,2)],k->IsPrime(k)and IsPrime(n-k))

Nie sądzę, że GAP ma krótszą drogę niż ta oczywista. Numberzlicza, ile elementów listy spełnia predykat.

Używając go do obliczenia pierwszych 100 wartości:

gap> List([1..100],n->Number([2..QuoInt(n,2)],k->IsPrime(k)and IsPrime(n-k)));
[ 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 0, 1, 1, 2, 1, 2, 0, 2, 1, 2, 1, 3, 0, 3, 1, 
  3, 0, 2, 0, 3, 1, 2, 1, 4, 0, 4, 0, 2, 1, 3, 0, 4, 1, 3, 1, 4, 0, 5, 1, 4, 
  0, 3, 0, 5, 1, 3, 0, 4, 0, 6, 1, 3, 1, 5, 0, 6, 0, 2, 1, 5, 0, 6, 1, 5, 1, 
  5, 0, 7, 0, 4, 1, 5, 0, 8, 1, 5, 0, 4, 0, 9, 1, 4, 0, 5, 0, 7, 0, 3, 1, 6 ]
Christian Sievers
źródło
2

Brachylog , 22 bajty

:{,A:B>=.:#pa+?,.=}fl

Wypróbuj online!

Wyjaśnienie

Prosta transkrypcja problemu.

:{                }f       Find all valid outputs of the predicate in brackets for the Input
                    l      Output is the number of valid outputs found

  ,A:B>=.                  Output = [A, B] with A >= B
         :#pa              Both A and B must be prime numbers
             +?,           The sum of A and B is the Input
                .=         Label A and B as integers that verify those constraints
Fatalizować
źródło
2

Mathematica, 52 bajty

Count[IntegerPartitions[#,{2}]//PrimeQ,{True,True}]&

Wynik jest dostarczany jako funkcja anonimowa. Spróbuj narysować na nim wykres:

DiscretePlot[
 Count[IntegerPartitions[#, {2}] // PrimeQ, {True, True}] &[i], {i, 1,
   1000}]

wykres sekwencji

Nawiasem mówiąc, kod ma tę samą długość z wersją funkcji kodu demonstracyjnego w OEIS.

Keyu Gan
źródło
2
49 bajtów:PrimeQ[#~IntegerPartitions~{2}]~Count~{a=True,a}&
LegionMammal978
1

Galaretka , 12 bajtów

HRð,_@ÆPð×/S

TryItOnline
1-100

W jaki sposób?

HRð,_@ÆPð×/S - Main link: n    e.g. 22
H            - halve
 R           - range          [1,2,3,4,5,6,7,8,9,10,11] (note this will be 1 to n//2)
  ð          - dyadic chain separation
   ,         - pair with
    _@       - n -           [[1,2,3,4,5,6,7,8,9,10,11],[21,20,19,18,17,16,15,14,13,12,11]]
      ÆP     - is prime? (1 if prime 0 if not)
                            [[0,1,1,0,1,0,1,0,0,0,1],[0,0,1,0,1,0,0,0,1,0,1]]
        ð    - dyadic chain separation
         ×/  - reduce with multiplication
                             [0,0,1,0,1,0,0,0,0,0,1]
           S - sum           3
Jonathan Allan
źródło
1

Rakieta 219 bajtów

(let*((pl(for/list((i n) #:when(prime? i))i))(ll(combinations(append pl pl)2))(ol'()))(for/list((i ll))(define tl(sort i >))
(when(and(= n(apply + i))(not(ormap(λ(x)(equal? x tl))ol)))(set! ol(cons tl ol))))(length ol))

Nie golfowany:

(define(f n)
 (let* ((pl                                   ; create a list of primes till n
          (for/list ((i n) #:when (prime? i))
            i))
         (ll (combinations (append pl pl) 2)) ; get a list of combinations of 2 primes
         (ol '()))                            ; initialize output list
    (for/list ((i ll))                        ; test each combination
      (define tl (sort i >))
      (when (and (= n (apply + i))            ; sum is n
                 (not(ormap (lambda(x)(equal? x tl)) ol))) ; not already in list
        (set! ol (cons tl ol))))              ; if ok, add to list
    (println ol)                              ; print list
    (length ol)))                             ; print length of list

Testowanie:

(f 10)
(f 100)

Wynik:

'((5 5) (7 3))
2
'((97 3) (89 11) (83 17) (71 29) (59 41) (53 47))
6
rnso
źródło
1

Właściwie 11 bajtów

;R`p`░@-♂bΣ

Wypróbuj online!

Wyjaśnienie:

;R`p`░@-♂bΣ
 R`p`░       prime values in [1, n]
;     @-     subtract each value from n
        ♂b   convert each value to boolean
          Σ  sum
Mego
źródło
1

05AB1E , 6 bajtów

;ÅP-pO

Wypróbuj online!

Wyjaśnienie:

                  # implicit input (example: 10)
;                 # divide input by 2 (5)
 ÅP               # primes up to that ([2, 3, 5])
   -              # subtract from the implict input ([8, 7, 5])
    p             # isPrime? ([0, 1, 1])
     O            # sum (2), implicit output
Ponury
źródło
0

Haskell, 73 bajty

f n|r<-[a|a<-[2..n],all((<2).gcd a)[2..a-1]]=sum[1|p<-r,q<-r,q<=p,p+q==n]

Przykład użycia: map f [1..25]-> [0,0,0,1,1,1,1,1,1,2,0,1,1,2,1,2,0,2,1,2,1,3,0,3,1].

Bezpośrednie wdrożenie definicji: najpierw wiążą rwszystkich liczb pierwszych w górę do liczby wejściowej n, a następnie wziąć 1na zawsze pi qod rgdzie q<=pa p+q==ni zsumować je.

nimi
źródło