Python, 89 86 85 octets
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
L'algorithme est O (effrayant) pour commencer et la récursivité n'aide pas vraiment, mais il fonctionne bien tant que n est suffisamment proche d'un nombre 7DP.
Merci à @xnor d'avoir joué au golf sur 3 octets!
Testez - le sur repl.it .
Comment ça fonctionne
Python n'a pas de primalité ou de factorisation intégrée, mais nous pouvons identifier les nombres 7DP par la quantité et la nature de leurs diviseurs.
Par le principe de multiplication, le nombre de diviseurs d'un entier peut être calculé comme le produit des exposants incrémentés de sa factorisation première. Ainsi, σ 0 (n) ( fonction de diviseur ) vaut 2 m chaque fois que n est un nombre mDP.
σ 0 (n) = 128 est donc une condition nécessaire, mais elle n'est pas suffisante; par exemple, σ 0 (2 127 ) = 128 , mais 2 127 n'est clairement pas un nombre 7DP. Cependant, si σ 0 (n) = 128 et qu'aucun carré parfait ne divise n également, alors n est un nombre 7DP.
Pour l'entrée n , l'algorithme consiste à inspecter les entiers n , n - 1 , n + 1 , n - 2 , n + 2 , etc. et à renvoyer le premier qui est un nombre 7DP.
Lorsque f est appelé avec l'argument n , les événements suivants se produisent:
Le code
126^sum(1>>n%i<<7*(n/i%i<1)for i in range(2,n))
teste si n n'est pas un nombre 7DP comme suit.
Pour tous les entiers i tels que 1 <i <n , 1>>n%i<<7*(n/i%i<1)
est évalué.
Si n est divisible par i mais pas par i 2 , 1>>n%i
donne 1 et (n/i%i<1)
donne 0 , ce qui donne
1 · 2 7 · 0 = 1 .
Si n est divisible par i 2 , 1>>n%i
et les (n/i%i<1)
deux donnent 1 , ce qui donne 1 · 2 7 · 1 = 128 .
Si n n'est pas divisible par i , 1>>n%i
donne 0 , ce qui donne 0 · 2 7 · x = 0 .
La somme des nombres entiers résultants sera 2 m - 2 si n est un nombre MDP (ses 2 m de diviseurs, à l' exclusion 1 et n ) et un plus grand nombre de de 127 , si n a un facteur carré parfait. Ainsi, la somme sera 126 si et seulement si n est un nombre 7DP.
Pour les nombres 7DP, la somme est 126 , donc XOR avec 126 donne 0 , ce qui est faux. Ainsi, la ou la partie du lambda est exécutée et f renvoie la valeur actuelle de n .
Si n n'est pas un nombre 7DP, XOR renverra une valeur véridique non nulle. Ainsi, la partie et de la lambda est exécutée.
f(n+k,k%2*2+~k)
appelle récursivement f avec des valeurs mises à jour de n (le prochain nombre potentiel 7DP) et k (la différence entre le nouveau candidat et celui qui suit).
Si k est un entier pair non négatif, k%2*2
donne 0 et ~k
donne - (k + 1) . La somme des deux résultats est - (k + 1) , qui est un entier impair impair qui est supérieur de 1 en valeur absolue à k .
Si k est un entier impair impair, k%2*2
donne 2 et ~k
donne - (k + 1) . La somme des deux résultats est 2 - (k + 1) = - (k - 1) , qui est un entier pair non négatif qui est 1 unité supérieur en valeur absolue à k .
Cela signifie que k prend les valeurs 0, -1, 2, -3, 4, ⋯ .
Lorsqu'ils sont ajoutés cumulativement à n 0 (la valeur initiale de n ), les entiers résultants sont
- 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.
assurant que le premier numéro de 7DP que nous rencontrons est aussi proche de n 0 que possible.
k
directement enf(n+k,k%2*2+~k)
commençant park=0
.Brachylog ,
444016 octetsBiffé 44 est toujours régulier 44; (
Exemple:
Se pourrait-il que cette langue ne suce pas toujours? J'ai battu Jelly et MATL!
Le cas de test avec
5
est le plus long et prend environ 10 secondes sur ma machine.Ce serait 12 octets s'il
$p
n'était pas buggé (nous n'aurions pas besoin de la>0,.
partie)Explication
Brachylog utilise la programmation logique par contrainte par défaut pour toute l'arithmétique entière. De plus, l'étiquetage intégré
=
fonctionne sur des domaines éventuellement infinis.Il unifie successivement une variable sans contraintes (dans
(-inf, inf)
) en tant que tels:0, 1, -1, 2, -2, 3, …
.Par conséquent, nous pouvons obtenir le numéro 7DP le plus proche en recherchant le premier numéro
I
unifié dans(-inf, inf)
(à l'aide du retour automatique), quiInput + I
est un numéro 7DP.la source
$p
. En théorie, je n'en ai pas besoin>0,
, mais mon implémentation est boguée: PInput+1, Input-1, Input+2, Input-2, Input+3, ...
donc le premier 7DP trouvé avec cette méthode sera le plus proche.>0,.
pas nécessaire)Gelée, 17 octets
Fonctionne en théorie, mais prend plusieurs années.
Voici une version qui fonctionne réellement pour les entrées données, mais échoue théoriquement pour les grandes entrées:
Essayez-le ici. Cela génère tous les nombres premiers jusqu'à 50, puis trouve toutes les 7 combinaisons de nombres premiers dans cette liste, puis tous leurs produits. Enfin, il trouve simplement l'élément le plus proche de cette liste à l'argument donné.
Bien sûr, une fois que nos 7DP contiennent des nombres premiers supérieurs à 50, cela échouera. La version théorique génère tous les nombres premiers jusqu'à 256n pour une entrée n , mais fonctionne autrement de la même manière.
Preuve
Soit
p(x)
le premier prime suivantx
. Une limite supérieure (extrêmement lâche) pour le produit 7DP le plus proche de x est:Il nous suffit donc de vérifier les nombres premiers dans [2… p (p (p (p (p (p (p (x)))))))]] . Le postulat de Bertrand dit que p (x) ≤ 2x , il suffit donc de vérifier tous les nombres premiers jusqu'à 128x .
la source
×⁹ÆRœc7P€µạ³ỤḢị
ou×⁹ÆRœc7P€µạ³NMị
(impression du tableau de toutes les solutions) économise quelques octets. En outre,×⁹
peut être modifié pour+⁴
améliorer l' efficacité.MATL ,
2117161413 octetsMerci à Dennis pour une suggestion qui a supprimé 4 octets, et une autre qui a sauvé 1 octet de plus!
Cela fonctionne en théorie, mais manque de mémoire pour les entrées ci-dessus
6
(compilateur en ligne).Une version plus efficace utilise 21 octets et calcule tous les cas de test en environ une seconde:
Essayez-le en ligne!
Explication
Version économe en mémoire
Prenez l'entrée N =
860782
comme exemple. Il suffit de considérer les nombres premiers à M =29
, qui est le premier premier que multiplié par2*3*5*7*11*13
excède N . Dans cet exemple2*3*5*7*11*13*29 = 870870
,. Le premier prime est31
. Tout produit impliquant que le premier ou plus sera au moins2*3*5*7*11*13*31 = 930930
, et il est donc garanti pas être la solution, car elle dépasse ce870870
qui est supérieur à N .M est calculé comme le premier nombre premier supérieur à
max(N/(2*3*5*7*11*13), 16)
. Lamax
fonction est utilisée pour s'assurer qu'au moins17
est sélectionné. Pour économiser quelques octets, le code remplace2*3*5*7*11*13 = 30030
par30000
et fonctionnemax
par addition. Ces modifications sont valides car elles donnent une valeur plus élevée.Version à mémoire insuffisante
Pour réduire davantage le nombre d'octets, la division peut être supprimée; en fait, il suffit de multiplier par
17
(merci, @Dennis). Cela garantit que le prochain nombre premier est inclus (par le postulat de Bertrand ) et que le résultat est au moins17
. Cela fonctionne en théorie, mais manque de mémoire pour des entrées plus grandes qu'environ6
.Dans le code, la section
est remplacé par
la source
Pyke, 32 octets
Essayez-le ici!
Notez que cela ne fonctionne pas en ligne - cela arrive à expiration. Cette version ne vérifie que 2 nombres premiers distincts et devrait fonctionner plus rapidement. Lorsqu'il y a 2 numéros de la même distance de la cible, il choisit celui du bas.
Cela passe par tous les nombres jusqu'à ce qu'il en trouve un qui soit plus grand que l'entrée et qui soit un 7DP. Pour chaque numéro, il s'en débarrasse s'il ne s'agit pas d'un 7DP. Il a ensuite une liste de 7DP jusqu'à l'entrée avec un plus grand. Il sélectionne ensuite celui qui est le plus proche de l'entrée.
la source
Julia, 59 octets
C’est très inefficace, mais cela fonctionne pour le premier cas de test en pratique et pour les autres en théorie.
Au prix de 5 octets supplémentaires - pour un total de 64 octets - l'efficacité peut être considérablement améliorée.
Essayez-le en ligne!
Contexte
Comme mentionné dans la réponse de @ LuisMendo , l'ensemble des nombres premiers que nous devons considérer pour le nombre 7DP le plus proche est assez petit. Il suffit que l'ensemble contienne un nombre 7DP plus grand que l'entrée n , ce qui sera vrai si et seulement s'il contient un nombre premier p ≥ 17 tel que 30300p = 2 · 3 · 5 · 7 · 11 · 13 · p ≥ n .
Dans l'intervalle contenant au moins un nombre premier prouve que l'intervalle [x, 1,5x) contient au moins un nombre premier chaque fois que x ≥ 8 . Depuis 30030/16384 ≈ 1,83 , cela signifie qu'il doit être un nombre premier p à (n / 30030, n / 16384) à chaque fois que n> 8 · 30.300 = 242.400 .
Enfin, lorsque n <510510 , p = 17 est clairement suffisant, il suffit donc de considérer les nombres premiers jusqu'à n / 16384 + 17 .
Au détriment de l'efficacité, nous pouvons plutôt considérer des nombres premiers jusqu'à 17n . Cela fonctionne lorsque n = 1 et est largement supérieur à n / 16384 + 17 pour des valeurs plus grandes de n .
Comment ça fonctionne
17n|>primes
etn>>14+17|>primes
(le décalage de bits équivaut à la division par 2 14 = 16384 ) calculer les plages premières mentionnées dans le paragraphe précédent. Ensuite,combinations(...,7)
calcule tous les tableaux de sept nombres premiers différents dans cette plage, et le mappageprod
sur ceux-ci calcule leurs produits, c'est-à-dire les nombres 7DP à partir desquels nous choisirons la réponse.Ensuite,
-n
soustrayez n prom chaque numéro 7DP, puis triezsort(...,by=abs)
ces différences par leurs valeurs absolues. Enfin, nous sélectionnons la première différence avec[]
et calculons le nombre 7DP correspondant en ajoutant n avec+n
.la source
Pyth, 30 octets
Essayez-le en ligne!
Suite de tests.
(5 prend trop de temps à courir)
Explication
la source
Mathematica
136 8075 octetsIl s'agit d'une approche simple, allant de l'extérieur
n
.n
est un produit à 7 nombres premiers distincts si le nombre de facteurs premiers est 7 (PrimeNu@#==7
) et aucun de ces facteurs n'apparaît plus d'une fois (SquareFreeQ@#&
).Ma communication antérieure (136 octets) a trouvé à la fois le premier produit 7-prime-prime ci
n
- dessus et, s'il existe, le premier 7-distinct-prime product ci-dessousn
. Il a ensuite simplement déterminé ce qui était le plus prochen
. Si les produits étaient équidistants, il retournait les deux.La version actuelle vérifie n-1, n + 1, n-2, n + 2 ... jusqu'à ce qu'elle atteigne le premier produit 7-prime-prime. Cette version plus efficace adopte l'approche adoptée par Dennis.
L'avancée clé consistait à utiliser
⌊k/2](-1)^k⌋
pour renvoyer la série, 0, 1, -1, 2, -2 ... Le zéro est utilisé pour vérifier s'iln
s'agit lui-même d'un produit à 7 nombres distincts. Pour cette raison,Floor
(c'est-à-dire⌊...⌋
) est utilisé à la place deCeiling
.510510
870870
1438710
la source
05AB1E , 10 octets
Essayez-le en ligne!
Essaie toutes les combinaisons de 7 des 10 premiers nombres premiers d'entrée **. Manque de mémoire pour les entrées supérieures à 1.
Version 14 octets considérablement plus efficace:
Essayez-le en ligne!
Utilise les premiers nombres premiers (entrée / 100000 + 7).
la source