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
Para empezar, el algoritmo es O (aterrador) y la recursión realmente no ayuda, pero funciona bien siempre que n esté lo suficientemente cerca de un número de 7DP.
¡Gracias a @xnor por jugar golf 3 bytes!
Probarlo en repl.it .
Cómo funciona
Python no tiene funciones integradas de primalización o factorización, pero podemos identificar los números 7DP por la cantidad y la naturaleza de sus divisores.
Por el principio de multiplicación, el número de divisores de un número entero se puede calcular como el producto de los exponentes incrementados de su factorización prima. Por lo tanto, σ 0 (n) ( función divisor ) es 2 m siempre que n sea un número mDP.
σ 0 (n) = 128 es, por lo tanto, una condición necesaria, pero no es suficiente; por ejemplo, σ 0 (2 127 ) = 128 , pero 2 127 claramente no es un número 7DP. Sin embargo, si σ 0 (n) = 128 y ningún cuadrado perfecto divide n uniformemente, entonces n es un número de 7DP.
Para la entrada n , el algoritmo consiste en inspeccionar los enteros n , n - 1 , n + 1 , n - 2 , n + 2 , etc. y devolver el primero que es un número 7DP.
Cuando se llama f con el argumento n , sucede lo siguiente:
El código
126^sum(1>>n%i<<7*(n/i%i<1)for i in range(2,n))
prueba si n no es un número 7DP de la siguiente manera.
Para todos los enteros i tal que 1 <i <n , 1>>n%i<<7*(n/i%i<1)
se evalúa.
Si n es divisible por i pero no por i 2 , se 1>>n%i
obtiene 1 y se (n/i%i<1)
obtiene 0 , lo que resulta en
1 · 2 7 · 0 = 1 .
Si n es divisible por i 2 , 1>>n%i
y (n/i%i<1)
ambos producen 1 , lo que resulta en 1 · 2 7 · 1 = 128 .
Si n no es divisible por i , se 1>>n%i
obtiene 0 , lo que resulta en 0 · 2 7 · x = 0 .
La suma de los números enteros resultantes será 2 m - 2 si n es un número MDP (sus 2 m divisores, excluyendo 1 y n ) y un mayor número de 127 si n tiene un factor cuadrado perfecto. Por lo tanto, la suma será 126 si y solo si n es un número 7DP.
Para los números 7DP, la suma es 126 , por lo que XOR con 126 produce 0 , lo cual es falso. Por lo tanto, la o parte de la lambda se ejecuta yf devuelve el valor actual de n .
Si n no es un número 7DP, XOR devolverá un valor verdadero distinto de cero. Por lo tanto, se ejecuta la parte y de la lambda.
f(n+k,k%2*2+~k)
llama recursivamente f con valores actualizados de n (el siguiente número potencial de 7DP) yk (la diferencia entre el nuevo candidato y el siguiente).
Si k es un entero par, no negativo, k%2*2
produce 0 y ~k
produce - (k + 1) . La suma de ambos resultados es - (k + 1) , que es un entero impar impar que es 1 mayor en valor absoluto que k .
Si k es un entero impar, negativo, k%2*2
produce 2 y ~k
produce - (k + 1) . La suma de ambos resultados es 2 - (k + 1) = - (k - 1) , que es un número entero no negativo par que es 1 unidad mayor en valor absoluto que k .
Esto significa que k toma los valores 0, -1, 2, -3, 4, ⋯ .
Cuando se agregan acumulativamente a n 0 (el valor inicial de n ), los enteros resultantes son
- 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.
asegurándose de que el primer número 7DP que encontramos es lo más cercano a n 0 como sea posible.
k
directamente comof(n+k,k%2*2+~k)
, comenzando conk=0
.Brachylog ,
444016 bytesTachado 44 sigue siendo regular 44; (
Ejemplo:
¿Podría ser que este lenguaje no siempre apesta? ¡Le gané a Jelly y MATL!
El caso de prueba con
5
es el más largo y toma alrededor de 10 segundos en mi máquina.Esto sería de 12 bytes si
$p
no se corrigiera (no necesitaríamos la>0,.
parte)Explicación
Brachylog utiliza la programación de lógica de restricción por defecto para toda la aritmética de enteros. Además, el etiquetado integrado
=
funciona en dominios posiblemente infinitos.Se unifica sucesivamente una variable sin restricciones (es decir, en
(-inf, inf)
) como tal:0, 1, -1, 2, -2, 3, …
.Por lo tanto, podemos obtener el número 7DP más cercano al buscar el primer número
I
unificado en(-inf, inf)
(usando el seguimiento automático), para el cualInput + I
es un número 7DP.fuente
$p
. En teoría no necesito el>0,
, pero mi implementación tiene errores: PInput+1, Input-1, Input+2, Input-2, Input+3, ...
por lo tanto, el primer 7DP encontrado con ese método será el más cercano.>0,.
no es necesario)Jalea, 17 bytes
Funciona en teoría, pero lleva muchos años completarlo.
Aquí hay una versión que realmente funciona para las entradas dadas, pero teóricamente falla para entradas grandes:
Pruébalo aquí. Esto genera todos los primos hasta 50, luego encuentra todas las 7 combinaciones de primos en esa lista y luego todos sus productos. Finalmente, simplemente encuentra el elemento más cercano de esa lista al argumento dado.
Por supuesto, una vez que nuestros 7DP contengan primos superiores a 50, esto fallará. La versión teórica genera todos los números primos hasta 256n para una entrada n , pero por lo demás funciona de la misma manera.
Prueba
Deje
p(x)
denotar el siguiente primo despuésx
. Un límite superior (extremadamente suelto) para el producto 7DP más cercano a x es:Por lo tanto, solo necesitamos verificar los números primos en [2… p (p (p (p (p (p (p (p (x))))))))]] . El postulado de Bertrand dice que p (x) ≤ 2x , por lo que es suficiente verificar todos los primos hasta 128x .
fuente
×⁹ÆRœc7P€µạ³ỤḢị
o×⁹ÆRœc7P€µạ³NMị
(imprimiendo la matriz de todas las soluciones) guarda un par de bytes. Además,×⁹
se puede cambiar+⁴
para mejorar la eficiencia.MATL ,
2117161413 bytes¡Gracias a Dennis por una sugerencia que eliminó 4 bytes y otra que ahorró 1 byte más!
Esto funciona en teoría, pero se queda sin memoria para las entradas anteriores
6
(compilador en línea).Una versión más eficiente usa 21 bytes y calcula todos los casos de prueba en aproximadamente un segundo:
Pruébalo en línea!
Explicación
Versión de memoria eficiente
Tome la entrada N =
860782
como ejemplo. Es suficiente considerar primos hasta M =29
, que es el primer primo multiplicado por2*3*5*7*11*13
excede N . En este ejemplo2*3*5*7*11*13*29 = 870870
,. El próximo primo es31
. Cualquier producto que implica que el primer o mayor habrá por lo menos2*3*5*7*11*13*31 = 930930
, y por lo que está garantizado no ser la solución, porque excede870870
el cual supera N .M se calcula como el primer primo mayor que
max(N/(2*3*5*7*11*13), 16)
. Lamax
función se utiliza para garantizar que al menos17
se elija. Para guardar algunos bytes, el código reemplaza2*3*5*7*11*13 = 30030
por30000
y funcionamax
por adición. Estos cambios son válidos porque dan un valor mayor.Versión con memoria ineficiente
Para reducir aún más el número de bytes, se puede eliminar la división; de hecho, es suficiente multiplicar por
17
(gracias, @Dennis). Esto asegura que se incluya el próximo número primo (según el postulado de Bertrand ) y que el resultado sea al menos17
. Esto funciona en teoría, pero se queda sin memoria para entradas más grandes que aproximadamente6
.En el código, la sección
es reemplazado por
fuente
Pyke, 32 bytes
Pruébalo aquí!
Tenga en cuenta que esto no funciona en línea, se agota el tiempo de espera. Esta versión solo busca 2 primos distintos y debería funcionar más rápido. Cuando hay 2 números de la misma distancia del objetivo, elige el más bajo.
Esto pasa por todos los números hasta que encuentra uno que es más grande que la entrada y es un 7DP. Para cada número, se deshace de él si no es un 7DP. Luego tiene una lista de 7DP hasta la entrada con una que es más grande. Luego elige el que está más cerca de la entrada.
fuente
Julia, 59 bytes
Esto es muy ineficiente, pero funciona para el primer caso de prueba en la práctica y para los demás en teoría.
Con el costo de 5 bytes más, para un total de 64 bytes , la eficiencia se puede mejorar dramáticamente.
Pruébalo en línea!
Antecedentes
Como se menciona en la respuesta de @ LuisMendo , el conjunto de números primos que tenemos que considerar para el número 7DP más cercano es bastante pequeño. Es suficiente que el conjunto contenga un número 7DP que sea mayor que la entrada n , que será verdadero si y solo si contiene un primo p ≥ 17 tal que 30300p = 2 · 3 · 5 · 7 · 11 · 13 · p ≥ n .
En On, el intervalo que contiene al menos un número primo prueba que el intervalo [x, 1.5x) contiene al menos un número primo siempre que x ≥ 8 . Desde 30030/16384 ≈ 1,83 , que significa que debe haber un primer p en (n / 30030, n / 16384) cuando n> 8 · 30300 = 242400 .
Finalmente, cuando n <510510 , p = 17 es claramente suficiente, por lo que solo necesitamos considerar primos hasta n / 16384 + 17 .
A costa de la eficiencia, podemos considerar primos de hasta 17n . Esto funciona cuando n = 1 y es mucho mayor que n / 16384 + 17 para valores mayores de n .
Cómo funciona
17n|>primes
yn>>14+17|>primes
(el desplazamiento de bits es equivalente a dividir por 2 14 = 16384 ) calcular los rangos primos mencionados en el párrafo anterior. Luego,combinations(...,7)
calcula todas las matrices de siete números primos diferentes en ese rango, y asignaprod
sobre esos calcula sus productos, es decir, los números 7DP de los cuales elegiremos la respuesta.Luego,
-n
resta n prom cada número 7DP, luegosort(...,by=abs)
clasifica esas diferencias por sus valores absolutos. Finalmente, seleccionamos la primera diferencia con[]
y calculamos el número 7DP correspondiente agregando n con+n
.fuente
Pyth, 30 bytes
Pruébalo en línea!
Banco de pruebas.
(5 tarda demasiado en correr)
Explicación
fuente
Mathematica
136 8075 bytesEste es un enfoque directo, trabajando desde afuera
n
.n
es un producto primo distinto de 7 si el número de factores primos es 7 (PrimeNu@#==7
) y ninguno de estos factores aparece más de una vez (SquareFreeQ@#&
).Mi presentación anterior (136 bytes) encontró el primer producto de 7 primos distintos arriba
n
y, si existe, el primer producto de 7 primos distintos abajon
. Entonces simplemente determinó cuál estaba más cercan
. Si los productos eran equidistantes, devolvería ambos.La versión actual verifica n-1, n + 1, n-2, n + 2 ... hasta que alcanza el primer producto 7-prime-prime. Esta versión más eficiente adopta el enfoque que tomó Dennis.
El avance clave se usó
⌊k/2](-1)^k⌋
para devolver la serie, 0, 1, -1, 2, -2 ... El cero se usa para verificar sin
es un producto de 7 primos distintos. Por esta razón,Floor
(es decir,⌊...⌋
) se usa en lugar deCeiling
.510510
870870
1438710
fuente
05AB1E , 10 bytes
Pruébalo en línea!
Intenta todas las combinaciones de 7 de los primeros 10 ** primos de entrada. Se queda sin memoria para entradas mayores de 1.
Considerablemente más eficiente versión de 14 bytes:
Pruébalo en línea!
Utiliza los primeros primos (input / 100000 + 7).
fuente