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
O algoritmo é O (assustador) e a recursão não ajuda muito, mas funciona bem desde que n seja suficientemente próximo de um número 7DP.
Graças a @xnor por jogar fora 3 bytes!
Testá-lo em repl.it .
Como funciona
O Python não possui embutidos de primalidade ou fatoração, mas podemos identificar os números 7DP pela quantidade e natureza de seus divisores.
Pelo princípio da multiplicação, o número de divisores de um número inteiro pode ser calculado como o produto dos expoentes incrementados de sua fatoração primária. Assim, σ 0 (n) ( função divisora ) é 2 m sempre que n é um número mDP.
σ 0 (n) = 128 é, portanto, uma condição necessária, mas não é suficiente; por exemplo, σ 0 (2 127 ) = 128 , mas 2 127 claramente não é um número 7DP. No entanto, se ambos σ 0 (n) = 128 e nenhum quadrado perfeito divide n uniformemente, então n é um número 7DP.
Para a entrada n , o algoritmo consiste em inspecionar os números inteiros n , n - 1 , n + 1 , n - 2 , n + 2 , etc. e retornar o primeiro número 7DP.
Quando f é chamado com o argumento n , acontece o seguinte:
O código
126^sum(1>>n%i<<7*(n/i%i<1)for i in range(2,n))
testa se n não é um número 7DP da seguinte maneira.
Para todos os números inteiros i, de modo que 1 <i <n , 1>>n%i<<7*(n/i%i<1)
é avaliado.
Se n é divisível por i, mas não por i 2 , 1>>n%i
produz 1 e (n/i%i<1)
produz 0 , resultando em
1 · 2 7 · 0 = 1 .
Se n é divisível por i 2 , 1>>n%i
e (n/i%i<1)
ambos produzem 1 , resultando em 1 · 2 7 · 1 = 128 .
Se n não for divisível por i , 1>>n%i
produz 0 , resultando em 0 · 2 7 · x = 0 .
A soma dos números inteiros resultantes serão 2 m - 2 se n é um número (MDP seus dois m divisores, excluindo 1 e N ) e um número maior do que 127 se n tem um factor quadrado perfeito. Assim, a soma será 126 se e somente se n for um número 7DP.
Para números 7DP, a soma é 126 , portanto, XOR com 126 produz 0 , o que é falso. Assim, o ou parte do lambda é executado ef retorna o valor atual de n .
Se n não for um número 7DP, o XOR retornará um valor verdadeiro diferente de zero. Assim, a parte e do lambda é executada.
f(n+k,k%2*2+~k)
chama recursivamente f com valores atualizados de n (o próximo número 7DP em potencial) ek (a diferença entre o novo candidato e o seguinte).
Se k é um número inteiro par, não negativo, k%2*2
produz 0 e ~k
produz - (k + 1) . A soma dos dois resultados é - (k + 1) , que é um número inteiro ímpar negativo que é 1 maior em valor absoluto que k .
Se k é um número inteiro ímpar, negativo, k%2*2
produz 2 e ~k
produz - (k + 1) . A soma dos dois resultados é 2 - (k + 1) = - (k - 1) , que é um número inteiro par não negativo que é 1 unidade maior em valor absoluto que k .
Isso significa que k assume os valores 0, -1, 2, -3, 4, ⋯ .
Quando adicionados cumulativamente a n 0 (o valor inicial de n ), os números inteiros resultantes são
- 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.
certificando-se o primeiro número 7DP que encontramos é tão perto de n 0 possível.
k
diretamente comof(n+k,k%2*2+~k)
, começando comk=0
.Braquilog ,
444016 bytesO riscado 44 ainda é regular 44;
Exemplo:
Será que esse idioma nem sempre é ruim? Eu venci Jelly e MATL!
O caso de teste com
5
é o mais longo e leva cerca de 10 segundos na minha máquina.Isso seria de 12 bytes se
$p
não fosse corrigido (não precisaríamos da>0,.
parte)Explicação
O Brachylog usa programação lógica de restrição por padrão para toda aritmética de número inteiro. Além disso, a etiquetagem interna
=
funciona em domínios possivelmente infinitos.É sucessivamente unifica uma variável sem restrições (isto é, em
(-inf, inf)
) tal como:0, 1, -1, 2, -2, 3, …
.Portanto, podemos obter o número 7DP mais próximo, procurando o primeiro número
I
unificado(-inf, inf)
(usando oInput + I
retorno automático), para o qual é um número 7DP.fonte
$p
. Em teoria, eu não preciso do>0,
, mas minha implementação é de buggy: PInput+1, Input-1, Input+2, Input-2, Input+3, ...
portanto, o primeiro 7DP encontrado com esse método será o mais próximo.>0,.
não é necessário)Gelatina, 17 bytes
Trabalha em teoria, mas leva muitos anos para ser concluído.
Aqui está uma versão que realmente funciona para as entradas fornecidas, mas teoricamente falha para entradas grandes:
Experimente aqui. Isso gera todos os números primos até 50, depois encontra todas as 7 combinações de números primos nessa lista e todos os seus produtos. Finalmente, ele simplesmente encontra o elemento mais próximo dessa lista para o argumento fornecido.
Obviamente, uma vez que nossos 7DPs contenham números primos maiores que 50, isso irá falhar. A versão teórica gera todos os números primos até 256n para uma entrada n , mas funciona da mesma maneira.
Prova
Vamos
p(x)
denotar o próximo primo depoisx
. Um limite superior (extremamente flexível) para o produto 7DP mais próximo de x é:Portanto, só precisamos verificar os números primos em [2… p (p (p (p (p (p (p (p (x)))))))] . O postulado de Bertrand diz que p (x) ≤ 2x , portanto basta verificar todos os números primos de até 128x .
fonte
×⁹ÆRœc7P€µạ³ỤḢị
ou×⁹ÆRœc7P€µạ³NMị
(imprimir a matriz de todas as soluções) economiza alguns bytes. Além disso,×⁹
pode ser alterado+⁴
para melhorar a eficiência.MATL ,
2117161413 bytesAgradecemos a Dennis por uma sugestão que removeu 4 bytes e outra que salvou mais 1 byte!
Isso funciona na teoria, mas fica sem memória para as entradas acima
6
(compilador online).Uma versão mais eficiente usa 21 bytes e calcula todos os casos de teste em cerca de um segundo:
Experimente online!
Explicação
Versão com memória eficiente
Tome a entrada N =
860782
como exemplo. Basta considerar primos até H =29
, que é o primeiro nobre que multiplicado por2*3*5*7*11*13
excede N . Neste exemplo2*3*5*7*11*13*29 = 870870
,. O próximo primo é31
. Qualquer produto que envolva que prime ou maior será, pelo menos2*3*5*7*11*13*31 = 930930
, e assim é garantido não ser a solução, porque excede870870
o que excede N .M é calculado como o primeiro primo maior que
max(N/(2*3*5*7*11*13), 16)
. Amax
função é usada para garantir que pelo menos17
seja selecionado. Para salvar alguns bytes, o código substitui2*3*5*7*11*13 = 30030
por30000
e funcionamax
por adição. Essas alterações são válidas porque fornecem um valor maior.Versão ineficiente em memória
Para reduzir ainda mais o número de bytes, a divisão pode ser removida; de fato, basta multiplicar por
17
(obrigado, @Dennis). Isso garante que o próximo primo seja incluído (pelo postulado de Bertrand ) e que o resultado seja pelo menos17
. Isso funciona na teoria, mas fica sem memória para entradas maiores que cerca de6
.No código, a seção
é substituído por
fonte
Pyke, 32 bytes
Experimente aqui!
Observe que isso não funciona on-line - é o tempo limite. Esta versão verifica apenas 2 números primos distintos e deve funcionar mais rapidamente. Quando existem 2 números da mesma distância do alvo, ele escolhe o menor.
Isso percorre todos os números até encontrar um que seja maior que a entrada e seja um 7DP. Para cada número, ele se livra se não for um 7DP. Em seguida, ele tem uma lista de 7DPs até a entrada com uma que é maior. Em seguida, escolhe o que está mais próximo da entrada.
fonte
Julia, 59 bytes
Isso é muito ineficiente, mas funciona para o primeiro caso de teste na prática e para os outros na teoria.
Ao custo de mais 5 bytes - para um total de 64 bytes - a eficiência pode ser melhorada drasticamente.
Experimente online!
fundo
Como mencionado na resposta de @ LuisMendo , o conjunto de números primos que devemos considerar para o número 7DP mais próximo é bastante pequeno. Basta que o conjunto contenha um número 7DP maior que a entrada n , que será verdadeira se e somente se contiver um valor inicial p ≥ 17 , de modo que 30300p = 2 · 3 · 5 · 7 · 11 · 13 · p ≥ n .
Em No intervalo que contém pelo menos um número primo, prova que o intervalo [x, 1,5x) contém pelo menos um número primo sempre que x ≥ 8 . Desde 30030/16384 ± 1,83 , isso significa que deve haver um p in prim (n / 30030, n / 16384) sempre que n> 8 · 30300 = 242400 .
Finalmente, quando n <510510 , p = 17 é claramente suficiente, portanto, precisamos considerar apenas primos até n / 16384 + 17 .
Ao custo da eficiência, podemos considerar primos de até 17n . Isso funciona quando n = 1 e é muito maior que n / 16384 + 17 para valores maiores de n .
Como funciona
17n|>primes
en>>14+17|>primes
(o deslocamento de bits é equivalente a dividir por 2 14 = 16384 ) calcula os intervalos primos mencionados no parágrafo anterior. Em seguida,combinations(...,7)
calcula todas as matrizes de sete números primos diferentes nesse intervalo e o mapeamentoprod
sobre esses calcula seus produtos, ou seja, os números 7DP dos quais escolheremos a resposta.Em seguida,
-n
subtrai n prom cada número 7DP esort(...,by=abs)
classifica essas diferenças por seus valores absolutos. Por fim, selecionamos a primeira diferença com[]
e calculamos o número 7DP correspondente adicionando n com+n
.fonte
Pitão, 30 bytes
Experimente online!
Suíte de teste.
(5 leva muito tempo para ser executado)
Explicação
fonte
Mathematica
136 8075 bytesEsta é uma abordagem simples, trabalhando a partir de fora
n
.n
é um produto com 7 primos distintos se o número de fatores primos for 7 (PrimeNu@#==7
) e nenhum desses fatores aparecer mais de uma vez (SquareFreeQ@#&
).Meu envio anterior (136 bytes) encontrou o primeiro produto com 7 pontos distintos acima
n
e, se existir, o primeiro produto com 7 pontos distintos abaixon
. Então, simplesmente determinava qual estava mais próximon
. Se os produtos fossem equidistantes, retornariam ambos.A versão atual verifica n-1, n + 1, n-2, n + 2 ... até atingir o primeiro produto 7-prime-prime. Esta versão mais eficiente adota a abordagem adotada por Dennis.
O avanço da chave estava em uso
⌊k/2](-1)^k⌋
para retornar as séries, 0, 1, -1, 2, -2 ... O zero é usado para verificar sen
é um produto primo com 7 distintas. Por esse motivo,Floor
(ou seja,⌊...⌋
) é usado em vez deCeiling
.510510
870870
1438710
fonte
05AB1E , 10 bytes
Experimente online!
Tenta todas as combinações de 7 dos primeiros 10 ** primos de entrada. Fica sem memória para entradas maiores que 1.
Versão 14 bytes consideravelmente mais eficiente:
Experimente online!
Usa os primeiros (input / 100000 + 7) primos.
fonte