A tarefa é encontrar um fator não trivial de um número composto.
Escreva um código que encontre um fator não trivial de um número composto o mais rápido possível, sujeito a que seu código não tenha mais que 140 bytes. A saída deve ser apenas o fator que você encontrou.
Seu código pode receber e fornecer resultados de qualquer maneira que seja conveniente, incluindo, por exemplo, como argumentos para uma função.
Casos de teste que listam todos os fatores (você só precisa gerar um)
187: 11 17
1679: 23 73
14369648346682547857: 1500450271 9576890767
34747575467581863011: 3628273133 9576890767
52634041113150420921061348357: 2860486313 5463458053 3367900313
82312263010898855308580978867: 264575131106459 311111111111113
205255454905325730631914319249: 2860486313 71755440315342536873
1233457775854251160763811229216063007: 1110111110111 1000000000063 1111111999999
1751952685614616185916001760791655006749: 36413321723440003717 48112959837082048697
Não pontuarei sua resposta no seguinte caso de teste difícil, que pode ser de interesse para o teste:
513231721363284898797712130584280850383: 40206835204840513073 12764787846358441471
Ponto
Sua pontuação é o tempo combinado para fatorar todos os casos de teste acima com uma penalidade de 10 minutos para cada fatoração com falha (todos arredondados para o segundo mais próximo). Seu código também deve funcionar para outros números inteiros, ou seja, não deve apenas codificar essas respostas.
Vou parar o seu código após 10 minutos.
Se duas pessoas obtiverem a mesma pontuação, a primeira resposta vence.
Restrições
Seu código não pode usar nenhuma função interna ou de biblioteca que execute a fatoração de número inteiro. Você pode assumir que a entrada leva menos de 256 bits. Todos os números de entrada serão compostos.
Como vou cronometrar?
Vou literalmente rodar time ./myprog
no meu sistema Ubuntu para fazer o tempo; por isso, forneça também um programa completo para rodar que inclua qualquer função que você definiu.
Uma observação para idiomas compilados
O tempo de compilação não deve demorar mais de 1 minuto na minha máquina.
Isso é realmente possível?
Se você ignorar as restrições de espaço, cada uma poderá ser fatorada em menos de 2 segundos no meu computador usando código Python puro + pypy.
Então, o que é um algoritmo de fatoração não trivial?
O algoritmo rho de Pollard é rápido e adequado para jogar golfe. É claro que existem muitas outras maneiras de fatorar um número inteiro também.
Ainda mais rápido é a peneira quadrática . Parece um sério desafio espremer isso em 140 bytes.
Pontuações principais
- SEJPM , 10 minutos de penalidade no último caso de teste + 16 segundos em Haskell
2 ** 1024
?2
ou2, 2
?Respostas:
Haskell,
100979189877267 BytesExperimente Online!
-3 bytes graças a @flawr
-6 bytes graças a @flawr novamente
-2 bytes graças a @flawr novamente
-2 bytes graças a um conjunto otimizado de parâmetros
-1 byte graças a @flawrs mais um tempo
-14 bytes graças a requisitos para ter apenas que gerar um fator
-5 bytes graças a @AndersKaseorg
Isso funciona para os 5 primeiros casos de teste em um tempo imperceptível.
Isso provavelmente expirará no maior caso de teste.
Em geral, isso geralmente retornará um fator não trivial no tempo proporcional à raiz quadrada do menor fator.
Ele não funcionará em todas as entradas porque não varia o polinômio e a detecção do caso excepcional é difícil de fazer em 140 bytes.
Também não produzirá a fatoração completa, mas sim um fator não trivial e a divisão da entrada por esse fator.
Também não classificará os fatores por tamanho.
O método utilizado é o Pollard-Rho-Factoring com o valor inicial padrão de 2 (com o
x^2+1
polinômio padrão aplicado uma vez) e o fator constante polinomial não padrão de 7 (porque1
não funcionou com 1679) para todas as avaliações posteriores.Programa completo (
factor.hs
):Compile como
$ ghc factor.hs
(necessidadesghc
instaladas).Executar como
$ ./factor <number>
.Exemplo de execução:
Código não destruído:
Calcula o fator não trivial chamando
g
com valores iniciais. O polinômio é pré-aplicado em 2 aqui e reaplicado no resultado (5), para que a entrada parag
(em uma cláusula "where" ) sempre possa ser usada prontamente para o teste de MDC.g
(a versão golfed usa infix#
) tenta calcular um fator não triviald
(na cláusula where na versão não golfed, em linha na golfed) como a diferença entre as duas entradas parag
, se for bem-sucedido, retorna o referido fator , mais tentativas. Aqui, ele pode gerarn
como saída se,a==b
e assim retornar apenas um fator trivial, a abordagem adequada para lidar com isso seria variar os valores iniciais desse evento ou alterar o polinômio.fonte
|1<2=s a#(s$s b)
poderia ser substituído por|c<-s b=s a#s c
Acho :): (também por que você não postar uma TIO link?)abs
, poisb
é sempre não-negativo. (Talvez você quis dizerabs$b-a
, masgcd
aceita argumentos negativos e sempre produz um resultado não negativo.) Isso reduz a menos de metade de um tweet!Pari / GP , 137 bytes, ~ 5 segundos
Usando as operações de curva elíptica incorporadas do GP (e alguns ajustes de parâmetros ocultos) :
ecm
é uma função que (deve) retornar um fator. Experimente online!Teste:
Ungolfed:
Infelizmente, lidar com os fatores 2 e 3 usa muitos bytes. Bytes que poderiam ter sido usados para adicionar um estágio 2:
fonte
Axioma, 137 bytes 9 minutos
acima da função p () que implementaria algo p-1 para fatorar abaixo o que copiar em um arquivo para teste na função p ()
resultados aqui:
fonte
Axioma, 10 minutos + 31 segundos
z () é a função rho, uma função de 137 bytes; ungolfed z () e chame-o de rho (). Supõe-se que gcd (0, n) = n, para que o loop pare e retorne para a falha n.
os resultados (z () são válidos para todos, exceto o último número 1751952685614616185916001760791655006749 permanecem sem fatoração (10 minutos))
fonte
Python 3 ,
10099 bytes,45 4039 segundos + 10 minutos de penalidadeExperimente online!
Usa Pollard-Rho com valor inicial 2 e polinômio x ^ 2 + 1.
fonte
pow
(com o terceiro argumento) para melhorar sua velocidade de execução.