Considere a função Remove(n, startIndex, count)
que remove count
dígitos do número n
começando do dígito na posição startIndex
. Exemplos:
Remove(1234, 1, 1) = 234
Remove(123456, 2, 3) = 156
Remove(1507, 1, 2) = 07 = 7
Remove(1234, 1, 4) = 0
Vamos chamar o número primo X frágil se todas as Remove
operações possíveis o tornarem não primo. Por exemplo, 80651 é um primo frágil porque todos os seguintes números não são primos:
651, 51, 1, 0, 8651, 851, 81, 8, 8051, 801, 80, 8061, 806, 8065
Objetivo
Escreva um programa que encontre o maior primo frágil. Edit: removeu o limite de tempo porque havia uma maneira relativamente justa de contorná-lo.
A pontuação é o número primo frágil encontrado pelo seu programa. Em caso de empate, a finalização anterior vence.
Regras
- Você pode usar qualquer idioma e qualquer biblioteca de terceiros.
- Você executa o programa em seu próprio hardware.
- Você pode usar testes probabilísticos de primalidade.
- Tudo está na base 10.
Entradas principais
- 6629 dígitos por Qualtagh (Java)
- 5048 dígitos por Emil (Python 2)
- 2268 dígitos por Jakube (Python 2)
Edit: eu adicionei minha própria resposta.
- 28164 dígitos pelo Suboptimus Prime, com base no algoritmo de Qualtagh (C #)
code-challenge
primes
Suboptimus Prime
fonte
fonte
Respostas:
Java -
314433226629 dígitos6 0{3314} 8969999
Esta solução é baseada na resposta de FryAmTheEggman .
E se cavarmos mais fundo?
Torna-se uma estrutura de árvore:
Vamos chamar o número R composto à direita se R e todas as suas terminações forem compostas.
Vamos iterar sobre todos os números compostos corretos da maneira primeira: 1, 9, 01, 81, 91, 09, 49, 69, 99, 001, 801, 901 etc.
Os números que começam com zero não são verificados quanto à primalidade, mas são necessários para criar mais números.
Procuraremos um número alvo N no formato X00 ... 00R, onde X é um de 4, 6, 8 ou 9 e R é o composto correto. X não pode ser primo. X não pode ser 0. E X não pode ser 1 porque se R termina com 1 ou 9, então N conteria 11 ou 19.
Se o XR contiver números primos após a operação "remover", o XYR os conteria também para qualquer Y. Portanto, não devemos percorrer ramificações a partir de R.
Seja X uma constante, digamos 6.
Pseudo-código:
Devemos limitar a quantidade de zeros, pois pode levar muito tempo para encontrar um número primo no formato X + zeros + R (ou para sempre, se todos eles forem compostos).
O código real é bastante detalhado e pode ser encontrado aqui .
O teste de primazia para números no intervalo int longo é realizado pela variante determinística do teste de Miller. Para os números do BigInteger, primeiro é realizada uma divisão de teste e, em seguida, o teste BailliePSW. É probabilístico, mas bastante certo. E é mais rápido que o teste de Miller-Rabin (devemos fazer muitas iterações para que números tão grandes em Miller-Rabin ganhem precisão suficiente).
Editar: a primeira tentativa estava incorreta. Também devemos ignorar os ramos que começam com R se X0 ... 0R é primo. Então X0 ... 0YR não seria primo frágil. Portanto, uma verificação adicional foi adicionada. Esta solução parece estar correta.
Editar 2: adicionada uma otimização. Se (X + R) é divisível por 3, (X + zeros + R) também é divisível por 3. Portanto, X + zeros + R) não podem ser primos nesse caso e esses Rs podem ser ignorados.
Edição 3: não era necessário pular dígitos primos se eles não estiverem na última ou na primeira posição. Portanto, finais como 21 ou 51 estão ok. Mas isso não muda muito.
Conclusões:
fonte
Python 2 -
1261221133717192268 dígitosExistem cerca de len (n) ^ 2 números resultantes de Remove (n, startIndex, count). Eu tentei minimizar esses números. Se houver muitos dígitos próximos um do outro, os mesmos números resultantes poderão ser ignorados, pois aparecem várias vezes.
Então eu levei ao extremo, apenas 9s e um pouco de prima no meio. Também dei uma olhada no primo frágil abaixo de 1 milhão e vi que existem primos tão frágeis. Procurar números com 2 9s no final funciona muito bem, não sei por quê. 1 número, 3 ou 4 9s no final resulta em números primos frágeis menores.
Ele usa o módulo pyprimes . Não tenho certeza, se é bom. Ele usa o teste miller_rabin, portanto é probabilístico.
O programa encontra esse primo frágil de 126 dígitos em cerca de 1 minuto e, durante o resto do tempo, procura sem sucesso.
editar:
Acabei de ver que você removeu o prazo. Vou executar o programa durante a noite, talvez alguns primos frágeis realmente grandes apareçam.
editar 2:
Tornei meu programa original mais rápido, mas ainda não há solução com mais de 126 dígitos. Então pulei no trem e procurei x 9s + 1 dígito + y 9s. A vantagem é que você deve verificar os números O (n) em busca de primalidade, se você o corrigir. Encontra um 1221 rapidamente.
editar 3:
Para o número de 2268 dígitos, eu uso o mesmo programa, apenas dividi o trabalho em vários núcleos.
fonte
Python 2.7 - 429623069
99993799Até o momento, nenhuma otimização. Apenas usando algumas observações triviais sobre números primos frágeis (graças a Rainbolt no bate-papo):
Apenas tentando fazer a bola rolar :)
Tecnicamente, esse processo dura um pouco mais de 15 minutos, mas verifica apenas um único número no tempo extra.
is_prime
é retirado daqui (isaacg o usou aqui ) e é probabilístico.Apenas uma observação: quando eu começo isso,
n=429623069
eu acordo482704669
. O dígito extra realmente parece matar essa estratégia ...fonte
Python 2,
828 dígitos5048 dígitosComo o @Jakube apontou, o primeiro prime que enviei não era realmente frágil devido a um erro no meu código. A correção do bug foi fácil, mas também tornou o algoritmo significativamente mais lento.
Limitei-me a um subconjunto facilmente pesquisável dos números primos frágeis, ou seja, aqueles que consistem apenas no dígito 9 e exatamente um dígito 7.
Eu usei a mesma
is_prime
função ( daqui ) como @FryAmTheEggman.Editar:
Fiz duas alterações para tornar o algoritmo mais rápido:
Tento pular o máximo de checagens de primalidade possível e só volto quando um potencial frágil em potencial é encontrado para garantir que ele seja realmente frágil. Há um pequeno número de verificações duplicadas, então memorizei grosseiramente a função de verificação primária.
Para os números do formulário
b*'9' + '7' + c*'9'
, limitei o tamanho deb
. Quanto menor o limite, menos números precisam ser verificados, mas as chances aumentam para não encontrar nenhum primo grande e frágil. Eu meio que escolhi arbitrariamente 222 como o limite.Com alguns milhares de dígitos, uma única verificação principal já pode demorar alguns segundos para o meu programa. Então, provavelmente não posso fazer muito melhor com essa abordagem.
Por favor, sinta-se livre para verificar a exatidão da minha submissão. Devido à verificação probabilística de primalidade, meu número não pode ser teoricamente primo, mas, se for, deve ser frágil. Ou eu fiz algo errado. :-)
fonte
C #,
1003928164 dígitosEdit: Eu fiz outro programa baseado no algoritmo de Qualtagh com algumas pequenas modificações:
Resposta antiga:
Existem alguns padrões notáveis para primos frágeis:
onde X pode ser 1, 2, 4, 5, 7 ou 8.
Para esses números, precisamos considerar apenas (comprimento - 1)
Remove
operações possíveis . As outrasRemove
operações produzem números duplicados ou obviamente compostos. Tentei procurar todos esses números com até 800 dígitos e notei que quatro padrões aparecem com mais frequência do que o restante: 8007001, 8004001, 9997999 e 6004009. Como Emil e Jakube estão usando o padrão 999X999, decidi usar 8004001 apenas para adicionar alguma variedade.Adicionei as seguintes otimizações ao algoritmo:
fonte
Haskell -
12201277 dígitos corrigidos para reais reaisMelhor - 1277 dígitos
Código Haskell
fonte