Nächstes 7-Distinct-Prime-Produkt

14

(per Chat )

Der OEIS-Eintrag A123321 listet die Folge von Zahlen auf, die das Produkt von sieben verschiedenen Primzahlen sind. Der Kürze halber nennen wir dies eine 7DP- Nummer. Die ersten paar Zahlen und ihre entsprechenden Teiler sind unten:

510510 = 2 * 3 * 5 * 7 * 11 * 13 * 17
570570 = 2 * 3 * 5 * 7 * 11 * 13 * 19
690690 = 2 * 3 * 5 * 7 * 11 * 13 * 23
746130 = 2 * 3 * 5 * 7 * 11 * 17 * 19

Hier besteht die Herausforderung darin, die nächstgelegene 7DP-Zahl in Bezug auf die absolute Entfernung von einer bestimmten Eingabe zu finden.

Eingang

Eine einzelne positive ganze Zahl n in einem beliebigen Format .

Ausgabe

Die nächste 7DP-Nummer zu n , ebenfalls in einem beliebigen geeigneten Format. Wenn zwei 7DP-Nummern für die nächstgelegene Nummer gebunden sind, können Sie eine oder beide ausgeben.

Regeln

  • Es kann davon ausgegangen werden, dass die Zahlen in den Standarddatentyp [int](oder einen gleichwertigen Typ) Ihrer Sprache passen .
  • Es ist entweder ein vollständiges Programm oder eine Funktion zulässig.
  • Standardlücken sind verboten.
  • Dies ist , daher gelten alle üblichen Golfregeln und der kürzeste Code gewinnt.

Beispiele

5 -> 510510
860782 -> 870870
1425060 -> 1438710 (or 1411410, or both)
AdmBorkBork
quelle

Antworten:

11

Python, 89 86 85 Bytes

f=lambda n,k=0:126^sum(1>>n%i<<7*(n/i%i<1)for i in range(2,n))and f(n+k,k%2*2+~k)or n

Der Algorithmus ist anfangs O (beängstigend) und die Rekursion hilft nicht wirklich, aber sie funktioniert gut, solange n einer 7DP-Zahl ausreichend nahe kommt.

Vielen Dank an @xnor für das Golfen mit 3 Bytes!

Testen Sie es auf repl.it .

Wie es funktioniert

Python hat keine eingebauten Primalitäts- oder Faktorisierungsfunktionen, aber wir können 7DP-Zahlen anhand der Anzahl und der Art ihrer Teiler identifizieren.

Durch das Multiplikationsprinzip kann die Anzahl der Teiler einer ganzen Zahl als Produkt der inkrementierten Exponenten ihrer Primfaktorisierung berechnet werden. Somit & sgr; 0 (n) ( Divisor - Funktion ) ist 2 m , wenn n eine Zahl mDP.

σ 0 (n) = 128 daher eine notwendige Bedingung, aber es ist nicht ausreichend; Zum Beispiel ist σ 0 (2 127 ) = 128 , aber 2 127 ist eindeutig keine 7DP-Zahl. Wenn jedoch sowohl σ 0 (n) = 128 als auch kein perfektes Quadrat n gleichmäßig teilt , ist n eine 7DP-Zahl.

Für die Eingabe n besteht der Algorithmus darin, die ganzen Zahlen n , n - 1 , n + 1 , n - 2 , n + 2 usw. zu untersuchen und die erste Zahl zurückzugeben, die eine 7DP-Zahl ist.

Wenn f mit dem Argument n aufgerufen wird , passiert Folgendes:

  • Der Code

    126^sum(1>>n%i<<7*(n/i%i<1)for i in range(2,n))

    Tests , wenn n ist nicht eine 7DP Zahl wie folgt.

    Für alle ganzen Zahlen i , so dass 1 <i <n , 1>>n%i<<7*(n/i%i<1)ausgewertet wird.

    • Wenn n durch i, aber nicht durch i 2 teilbar ist , 1>>n%iergibt sich 1 und 0 , woraus sich 1 · 2 7 · 0 = 1(n/i%i<1) ergibt .

    • Wenn n durch teilbare i 2 , 1>>n%iund (n/i%i<1)sowohl Ausbeute als 1 , was zu einem 1 · 2 7 · 1 = 128 .

    • Wenn n nicht durch i teilbar ist , 1>>n%iergibt sich 0 , was zu 0 · 2 · 7 · x = 0 führt .


    Die Summe der resultierenden ganzen Zahlen wird 2 m - 2 , wenn n eine Zahl mDP (IVS 2 m Divisoren, außer 1 und n ) , und eine Zahl größer als 127 , wenn n einen perfekten Quadrat Faktor hat. Somit ist die Summe genau dann 126, wenn n eine 7DP-Zahl ist.

  • Für 7DP Zahlen ist die Summe 126 , so XOR - Verknüpfung mit 126 Ausbeuten 0 , die falsy ist. Somit wird das Lambda oder ein Teil davon ausgeführt und f gibt den aktuellen Wert von n zurück .

  • Wenn n keine 7DP-Zahl ist, gibt XOR einen Wahrheitswert ungleich Null zurück. Somit wird der und Teil des Lambdas ausgeführt.

    f(n+k,k%2*2+~k)

    ruft rekursiv f mit aktualisierten Werten von n (der nächsten potenziellen 7DP-Zahl) und k (der Differenz zwischen dem neuen Kandidaten und dem darauf folgenden) auf.

    Wenn k eine gerade, nicht negative ganze Zahl ist, k%2*2ergibt sich 0 und ~kergibt sich - (k + 1) . Die Summe beider Ergebnisse ist - (k + 1) , was eine ungerade negative ganze Zahl ist, deren absoluter Wert 1 größer als der von k ist .

    Wenn k eine ungerade negative ganze Zahl ist, k%2*2ergibt sich 2 und ~kergibt sich - (k + 1) . Die Summe beider Ergebnisse ist 2 - (k + 1) = - (k - 1) , was eine gerade, nicht negative ganze Zahl ist, deren absoluter Wert 1 Einheit größer als der von k ist .

    Dies bedeutet, dass k die Werte 0, -1, 2, -3, 4, ⋯ annimmt .

    Wenn addiert zu n 0 (dem Anfangswert von n ) ergeben sich ganze Zahlen

    • n 0 + 0
    • ( n 0 + 0) - 1 = n 0 - 1
    • ( n 0 - 1) + 2 = n 0 + 1
    • ( n 0 + 1) - 3 = n 0 - 2
    • ( n 0 - 2) + 4 = n 0 + 2
    • etc.


    sicherstellen , dass die erste 7DP Zahl wir so nahe Begegnung n 0 wie möglich.

Dennis
quelle
Tolle Idee mit dem Divisor Counting! Ich denke, Sie können den abwechselnden Weg Golf spielen, indem Sie kdirekt als f(n+k,k%2*2+~k), beginnend mit aktualisieren k=0.
9.
Große Verbesserung. Vielen Dank!
Dennis
9

Brachylog , 44 40 16 Bytes

Durchgestrichen 44 ist immer noch regulär 44; (

:I=+.>0,.$pPdPl7

Beispiel:

?- run_from_atom(':I=+.>0,.$pPdPl7',1425060,Z).
Z = 1438710 .

Könnte es sein, dass diese Sprache nicht immer saugt? Ich habe Jelly und MATL geschlagen!

Der Testfall mit 5 ist der längste und dauert auf meinem Rechner ca. 10 Sekunden.

Dies wären 12 Bytes, wenn $pes nicht abgehört würde (wir würden das nicht brauchen)>0,. Teil )

Erläuterung

Brachylog verwendet standardmäßig die Constraint-Logik-Programmierung für alle ganzzahligen Arithmetiken. Darüber hinaus ist die Beschriftung eingebaut= funktioniert auf möglicherweise unendlichen Domänen.

Es vereinheitlicht sukzessive eine Variable ohne Einschränkungen (dh in (-inf, inf)) als solche:0, 1, -1, 2, -2, 3, … .

Daher können wir die nächstgelegene 7DP-Nummer ermitteln, indem wir nach der ersten Ieinheitlichen Nummer suchen (-inf, inf)(mithilfe der automatischen Rückverfolgung), für die Input + Ies sich um eine 7DP-Nummer handelt.

:I=                Label variables in [Input, I]. I has no constraints and Input is known
   +.              Unify Output with Input + I
     >0,           Output > 0 (wouldn't be needed if $p failed for numbers less than 1)
        .$pP       Unify P with the list of prime factors of Output
            dP     Check that P with duplicates removed is still P
              l7   Check that the length of P is 7
Tödlich
quelle
1
Ich habe Jelly und MATL geschlagen! Aber nur mit 0 Bytes :-P
Luis Mendo
1
@ LuisMendo Es wären 13 Bytes, wenn ich einen Fehler mit behebe $p. Theoretisch brauche ich das nicht >0,, aber meine Implementierung ist
fehlerhaft
1
@DavidC Ja, da es bei der Eingabe beginnt und dann alle Zahlen als solche probiert: Input+1, Input-1, Input+2, Input-2, Input+3, ...Daher ist die erste mit dieser Methode gefundene 7DP die nächstliegende.
Fatalize
1
@mat Das Beheben von Fehlern nach dem Posten der Herausforderung führt dazu, dass die Antwort nicht konkurriert. Ich werde sie also bei 16 >0,.
belassen
1
codegolf.stackexchange.com/a/111998/59995 Durchgestrichene 444 ist immer noch 444. Ich bin beeindruckt, wenn wir durchgestrichene
4444 sehen.
7

Gelee, 17 Bytes

Pµạ³,
×⁹ÆRœc7Ç€ṂṪ

Funktioniert theoretisch, dauert aber viele Jahre.


Hier ist eine Version, die tatsächlich für die angegebenen Eingaben funktioniert, bei großen Eingaben jedoch theoretisch fehlschlägt:

Pµạ³,
50ÆRœc7Ç€ṂṪ

Probieren Sie es hier aus. Dies generiert alle Primzahlen bis zu 50, findet dann alle 7-Kombinationen von Primzahlen in dieser Liste und dann alle ihre Produkte. Schließlich findet es einfach das Element, das dem angegebenen Argument von dieser Liste am nächsten kommt.

Sobald unsere 7DPs Primzahlen über 50 enthalten, schlägt dies natürlich fehl. Die theoretische Version generiert alle Primzahlen bis 256n für einen Eingang n , funktioniert aber ansonsten genauso.

Beweis

Lassen Sie p(x)bezeichnen die nächste Primzahl nach x. Eine (extrem lockere) Obergrenze für das 7DP-Produkt, das x am nächsten kommt, ist:

p(x) * p(p(x)) * p(p(p(x))) * ... * p(p(p(p(p(p(p(x)))))))

Wir müssen also nur die Primzahlen in [2… p (p (p (p (p (p (p (x)))))] prüfen . Bertrands Postulat besagt, dass p (x) ≤ 2x ist. Es reicht also aus, alle Primzahlen bis 128x zu überprüfen .

Lynn
quelle
×⁹ÆRœc7P€µạ³ỤḢịoder ×⁹ÆRœc7P€µạ³NMị(Drucken des Arrays aller Lösungen) spart ein paar Bytes. Auch ×⁹kann geändert werden, +⁴um die Effizienz zu verbessern.
Dennis
5

MATL , 21 17 16 14 13 Bytes

Vielen Dank an Dennis für einen Vorschlag, der 4 Bytes entfernt hat, und einen weiteren, der 1 Byte mehr gespart hat!

t17*Zq7XN!pYk

Dies funktioniert theoretisch, aber für die obigen Eingaben ist nicht genügend Speicher 6verfügbar (Online-Compiler).

Eine effizientere Version verwendet 21 Bytes und berechnet alle Testfälle in etwa einer Sekunde:

t3e4/k16+_YqZq7XN!pYk

Probieren Sie es online!

Erläuterung

Speichereffiziente Version

Nehmen Sie als Beispiel den Eingang N = 860782. Es reicht aus, Primzahlen bis zu M = zu betrachten. Dies 29ist die erste Primzahl, die mit 2*3*5*7*11*13mehr als N multipliziert wird . In diesem Beispiel 2*3*5*7*11*13*29 = 870870. Die nächste Primzahl ist 31. Jedes Produkt, an dem diese Primzahl oder höher beteiligt ist, ist mindestens eine 2*3*5*7*11*13*31 = 930930und daher ist dies garantiert nicht die Lösung, da es N870870 übersteigt .

M wird als erste Primzahl größer als berechnet max(N/(2*3*5*7*11*13), 16). Die maxFunktion wird verwendet, um sicherzustellen, dass mindestens 17ausgewählt wird. Um ein paar Bytes zu sparen, wird der Code 2*3*5*7*11*13 = 30030durch 30000und die Funktion maxdurch Addition ersetzt. Diese Änderungen sind gültig, da sie einen größeren Wert ergeben.

t      % Take input implicitly. Duplicate
3e4/k  % Divide input by 30000 and round down (rounding here is only needed
       % due to a bug in the "next prime" function)
16+    % Add 16
_Yq    % Next prime
Zq     % Prime numbers up to that value
7XN    % Combinations of those primes taken 7 at a time. Gives a 2D array
       % with each combination on a different row
!p     % Product of each row
Yk     % Output product that is closest to the input. Implicitly display

Ineffiziente Version des Speichers

Um die Anzahl der Bytes weiter zu verringern, kann die Unterteilung entfernt werden. Tatsächlich reicht es aus, mit 17(danke, @Dennis) zu multiplizieren . Dies stellt sicher, dass die nächste Primzahl enthalten ist (von Bertrands Postulat ) und dass das Ergebnis mindestens ist 17. Dies funktioniert theoretisch, aber bei Eingaben, die größer als ungefähr sind, geht der Arbeitsspeicher aus 6.

Im Code der Abschnitt

3e4/k  % Divide input by 30000 and round down (rounding here is only needed
       % due to a bug in the "next prime" function)
16+    % Add 16
_Yq    % Next prime

wird ersetzt durch

17*    % Multiply by 17
Luis Mendo
quelle
3

Pyke, 32 Bytes

#PDl 7q.ID}lRlqi*(#)DF-X,)R],She

Probieren Sie es hier aus!

Beachten Sie, dass dies online nicht funktioniert - es tritt eine Zeitüberschreitung auf. Diese Version prüft nur auf 2 verschiedene Primzahlen und sollte schneller funktionieren. Wenn sich 2 Zahlen in der gleichen Entfernung vom Ziel befinden, wählt es die niedrigere.

Dies durchläuft alle Zahlen, bis eine gefunden wird, die größer als die Eingabe ist und eine 7DP ist. Für jede Zahl wird sie entfernt, wenn es sich nicht um eine 7DP handelt. Es hat dann eine Liste von 7DPs bis zur Eingabe mit einer, die größer ist. Anschließend wird derjenige ausgewählt, der dem Eingang am nächsten liegt.

Blau
quelle
3

Julia, 59 Bytes

!n=sort(map(prod,combinations(17n|>primes,7))-n,by=abs)[]+n

Das ist sehr ineffizient, funktioniert jedoch für den ersten Testfall in der Praxis und für die anderen in der Theorie.

Auf Kosten von 5 weiteren Bytes - für insgesamt 64 Bytes - kann die Effizienz drastisch verbessert werden.

!n=sort(map(prod,combinations(n>>14+17|>primes,7))-n,by=abs)[]+n

Probieren Sie es online!

Hintergrund

Wie in @ LuisMendos Antwort erwähnt , ist die Menge der Primzahlen, die wir für die nächste 7DP-Zahl berücksichtigen müssen, recht klein. Es reicht aus , wenn die Menge eine 7DP-Zahl enthält, die größer als die Eingabe n ist. Dies gilt genau dann, wenn sie eine Primzahl p ≥ 17 enthält , sodass 30300p = 2 · 3 · 5 · 7 · 11 · 13 · p ≥ n .

Im On Das Intervall mit mindestens einer Primzahl beweist, dass das Intervall [x, 1.5x) mindestens eine Primzahl enthält, wenn x ≥ 8 ist . Da 30030/16384 ≈ 1,83 , bedeutet dies, dass es immer dann eine Primzahl p in (n / 30030, n / 16384) geben muss, wenn n> 8 · 30300 = 242400 .

Wenn schließlich n <510510 ist , ist p = 17 eindeutig ausreichend, sodass wir nur Primzahlen bis n / 16384 + 17 berücksichtigen müssen .

Auf Kosten der Effizienz können wir stattdessen Primzahlen bis 17n berücksichtigen . Dies funktioniert bei n = 1 und ist bei größeren Werten von n weitaus größer als n / 16384 + 17 .

Wie es funktioniert

17n|>primesund n>>14+17|>primes(die Bitverschiebung ist gleichbedeutend mit Teilen durch 2 14 = 16384 ) Berechnen Sie die im vorherigen Absatz genannten Primzahlenbereiche. Dann combinations(...,7)berechnet alle Anordnungen von sieben verschiedenen Primzahlen in diesem Bereich, und Kartierung prodüber diejenigen berechnet ihre Produkte, dh die 7DP Zahlen , aus denen wir die Antwort wählen würden.

Als nächstes -nsubtrahiert man dann n Prom für jede 7DP-Zahlsort(...,by=abs) sortiert diese Differenzen nach ihren absoluten Werten. Schließlich wählen wir die erste Differenz mit aus []und berechnen die entsprechende 7DP-Zahl durch Addition von n mit +n.

Dennis
quelle
2

Pyth, 30 Bytes

L&{IPbq7lPby#.W!syMH,hhZa0teZ,

Probieren Sie es online!

Testsuite.

(5 dauert zu lange)

Erläuterung

L&{IPbq7lPby#.W!syMH,hhZa0teZ,

L&{IPbq7lPb     Defines a function y, whose argument is b:
 &                  Return if both the following are true:
  {IPb                  the prime factorization contains no duplicate; and:
      q7lPb             the number of prime factors is 7

           y#.W!syMH,hhZa0teZ,   The main programme. Input as Q.
                             ,QQ Implicit arguments, yield [Q,Q].
             .W                  While
               !syMH                   both numbers do not satisfy y:
                    ,hhZ             increment the first number
                          teZ        and decrement the second number
                        a0           while making it non-negative.
Undichte Nonne
quelle
1

Mathematica 136 80 75 Bytes

Dies ist ein unkomplizierter Ansatz, von dem aus man nach außen arbeitet n .

nist ein Produkt mit 7 verschiedenen Primzahlen, wenn die Anzahl der Primfaktoren 7 ( PrimeNu@#==7) beträgt und keiner dieser Faktoren mehr als einmal vorkommt ( SquareFreeQ@#&).

g@n_:=(k=1;While[!(PrimeNu@#==7&&SquareFreeQ@#&)⌊z=n-⌊k/2](-1)^k⌋,k++];z)

Meine frühere Übermittlung (136 Bytes) fand sowohl das erste 7-verschiedene-Prim-Produkt oben nals auch, falls vorhanden, das erste 7-verschiedene-Prim-Produkt unten n. Es wurde dann einfach festgestellt, was näher war n. Wenn die Produkte äquidistant waren, wurden beide zurückgegeben.

Die aktuelle Version prüft n-1, n + 1, n-2, n + 2 ..., bis das erste Produkt mit 7 verschiedenen Primzahlen erreicht ist. Diese effizientere Version übernimmt den Ansatz von Dennis.

Der entscheidende Fortschritt war die Verwendung ⌊k/2](-1)^k⌋ , die Serien 0, 1, -1, 2, -2 zurückzugeben. Die Null wird verwendet, um zu überprüfen, ob nes sich selbst um ein Produkt mit 7 verschiedenen Primzahlen handelt. Aus diesem Grund wird Floor(das heißt ⌊...⌋) anstelle von verwendet Ceiling.


g[5]
g[860782]
g[1425060]

510510

870870

1438710

DavidC
quelle
1

05AB1E , 10 Bytes

°Åp7.ÆPs.x

Probieren Sie es online!

Versucht alle Kombinationen von 7 der ersten 10 ** Eingabeprimzahlen. Bei Eingaben größer als 1 ist nicht genügend Speicher verfügbar.

Deutlich effizientere 14-Byte-Version:

5°/7+Åp7.ÆPs.x

Probieren Sie es online!

Verwendet die ersten (Eingabe / 100000 + 7) Primzahlen.

Grimmig
quelle