Escreva um programa que verifique a conjectura de Erdős-Straus


15

Escreva o programa, que verifica a conjectura de Erdős-Straus .
Programa deve ter como entrada um inteiro n( 3 <= n <= 1 000 000) e imprimir o triplo de inteiros satisfazendo identidade 4/n = 1/x + 1/y + 1/z, 0 < x < y < z.

O menor código vence.

Alguns exemplos:

3 => {1, 4, 12}
4 => {2, 3, 6}
5 => {2, 4, 20}
1009 => {253, 85096, 1974822872}
999983 => {249996, 249991750069, 62495875102311369754692}
1000000 => {500000, 750000, 1500000}

Observe que seu programa pode imprimir outros resultados para esses números porque existem várias soluções.


O programa precisa produzir todas as soluções possíveis ou apenas uma? Por exemplo, existem 2 possibilidades para n = 5.
Izlin

1
Apenas um é suficiente.
Somnium 21/07

2
É um pouco enganador que seu único caso de teste não seja uma entrada válida, de acordo com as especificações.
Peter Taylor

Vou mudar, exemplo adicionado durron597.
Somnium 21/07

Eu adicionei esse exemplo porque minha pesquisa sugeriu que era particularmente difícil de fazer. Os mais difíceis são primos que são congruentes com {1, 121, 169, 289, 361, 529}modulo 840.
durron597

Respostas:


12

Ruby, 119106 caracteres

f=->s,c,a{m=s.to_i;c<2?m<s||(p a+[m];exit):(1+m...c*s).map{|k|f[s/(1-s/k),c-1,a+[k]]}}
f[gets.to_r/4,3,[]]

O código usa limites mínimos para cada variável, por exemplo n/4<x<3n/4, da mesma forma para y. Até o último exemplo retorna instantâneo (tente aqui ).

Exemplos:

> 12
[4, 13, 156]

> 123
[31, 3814, 14542782]

> 1234
[309, 190654, 36348757062]

> 40881241801
[10220310451, 139272994276206121600, 22828913614743204775214996005450198400]

Solução legal, no entanto, os limites são um pouco apertados, porque seu programa para 1 000 000 encontra uma solução melhor (veja meu exemplo).
Somnium 21/07

1
@ user2992539 Meu código retorna a primeira solução lexicograficamente (250001 <500000).
219 Howard

7

Mathematica 62

Esta solução de baunilha comum funciona bem - na maioria das vezes.

f@n_ := FindInstance[4/n == 1/x + 1/y + 1/z && 0 < x < y < z, {x, y, z}, Integers]

Exemplos e horários (em segundos)

AbsoluteTiming[f[63]]
AbsoluteTiming[f[123]]
AbsoluteTiming[f[1003]]
AbsoluteTiming[f[3003]]
AbsoluteTiming[f[999999]]
AbsoluteTiming[f[1000000]]

{0,313671, {{x -> 16, y -> 1009, z -> 1017072}}}
{0,213965, {{x -> 31, y -> 3814, z -> 14542782}}}
{0,212016, {{x -> 251, y -> 251754, z -> 63379824762}}}
{0,431834, {{x -> 751, y -> 2255254, z -> 5086168349262}}}
{1.500332, {{x -> 250000, y - > 249999750052, z -> 1201920673328124750000}}}
{1.126821, {{x -> 375000, y -> 1125000, z -> 2250000}}}


Mas não constitui uma solução completa. Existem alguns números que não podem ser resolvidos. Por exemplo,

AbsoluteTiming[f[30037]]
AbsoluteTiming[f[130037]]

{2.066699, FindInstance [4/30037 == 1 / x + 1 / y + 1 / z && 0 <x <y <z, {x, y, z}, Inteiros]}
{1.981802, FindInstance [4/130037 = = 1 / x + 1 / y + 1 / z && 0 <x <y <z, {x, y, z}, Inteiros]}


A ferramenta certa para o trabalho certo. +1
William Barbosa

3
@WilliamBarbosa eu diria que FindInstancenão é a ferramenta certa vez que não pode garantir um resultado ...
Howard

2
@Howard eu estava falando Mathematica, na verdade
William Barbosa

Reduceparece resolver os casos mais difíceis, embora muitas vezes leve tempo. Por exemplo, 15 minutos para encontrar 82 soluções para n = 10037.
21414

3

C #

Disclamer: esta não é uma resposta séria

Isso apenas reforça todas as possibilidades de 1 a 1 << 30. É enorme, lento, eu nem sei se funciona corretamente, mas segue as especificações literalmente, pois verifica a condição todas as vezes, o que é legal. Não testei isso porque o ideone tem um limite de 5 segundos para os programas e, portanto, isso não terminará a execução.

(Caso alguém esteja se perguntando: esse é um enorme tamanho de 308 bytes )

static double[]f(double n)
{
    for(double x=1;x<1<<30;x++)
    {
        for(double y=1;y<1<<30;y++)
        {
            for(double z=1;z<1<<30;z++)
            {
                if(4/n==1/x+1/y+1/z)
                    return new[]{x,y,z};
            }
        }
    }
    return null;
}

Atualização: corrigida para que realmente funcione


2
Não funciona (dica: divisão inteira).
219 Howard

Provavelmente não funcionará devido a erros de arredondamento.
Somnium 21/07

@ user2992539 funciona para mim, testei-o 5como entrada e deu o resultado correto ( 2, 4, 20) #
Christoph Böhmwalder

@HackerCow pode não funcionar para números inteiros grandes.
Somnium

1
@HackerCow você certamente pode economizar tempo começando com y = x + 1 e z = y + 1. Provavelmente será mais rápido usar a verificação equivalente 4xyz = n (xy + yz + xz), embora eu aceite que seja uma expressão mais longa e também tenha problemas de arredondamento.
Alchymist

3

Python 2 , 171 bytes

from sympy import*
def f(n):
 for d in xrange(1,n*n):
  for p in divisors(4*d+n*n):
   q=(4*d+n*n)/p;x=(n+p)/4;y=(n+q)/4
   if (n+p)%4+(n+q)%4+n*x*y%d<1:return x,y,n*x*y/d

Experimente online!

A primeira resposta é rápida o suficiente para ser exaustivamente testada. É capaz de encontrar soluções para todos os 3 ≤ n ≤ 1000000 em cerca de 24 minutos no total , com uma média de 1,4 milissegundos cada.

Como funciona

Reescreva 4 / n = 1 / x + 1 / y + 1 / z como z = n · x · y / d , em que d = 4 · x · y - n · x - n · y . Podemos então fatorar 4 · d + n 2 = (4 · x - n ) · (4 · y - n ), o que nos fornece uma maneira muito mais rápida de pesquisar x e y , desde que dé pequeno. Dado x < y < z , que pode, pelo menos, provar d <3 · n 2 /4 (daí o ligado no circuito externo), apesar de, na prática, tende a ser muito menor, 95% do tempo, podemos usar d = 1, 2 ou 3. O pior caso é n = 769129, para o qual o menor d é 1754 (este caso leva cerca de 1 segundo).


1

Mathematica, 99 bytes

f[n_]:=(x=1;(w=While)[1>0,y=1;w[y<=x,z=1;w[z<=y,If[4/n==1/x+1/y+1/z,Return@{x,y,z}];++z];++y];++x])

É uma força bruta bastante ingênua, por isso realmente não escala bem. Definitivamente vou chegar a um milhão (fique à vontade para considerar isso inválido por enquanto). n = 100leva meio segundo, mas n = 300já leva 12 segundos.


1

Golflua 75

ndo prompt (após a chamada no terminal), mas basicamente itera como a solução Hobbies da Calvin faz:

n=I.r()z=1@1~@y=1,z-1~@x=1,y-1?4*x*y*z==n*(y*z+x*z+x*y)w(n,x,y,z)~$$$z=z+1$

Uma versão Lua não destruída do acima é

n=io.read()
z=1
while 1 do
   for y=1,z-1 do
      for x=1,y-1 do
         if 4*x*y*z==n*(y*z+x*z+x*y) then
            print(n,x,y,z)
            return
         end
      end
   end
   z=z+1
end

Exemplos:

n=6     -->     3      4     12
n=12    -->     6     10     15
n=100   -->    60     75    100
n=1600  -->  1176   1200   1225

1

Python, 117

n=input();r=range;z=0
while 1:
 z+=1
 for y in r(z):
  for x in r(y):
    if 4*x*y*z==n*(y*z+x*z+x*y):print x,y,z;exit()

Exemplo:

16 --> 10 12 15

Nada muito especial.


1
Por que você define uma função se deseja chamá-la apenas uma vez?
Isaacg

@isaacg Ele precisa parar de alguma forma, mas o uso exit()diminui.
Hobbies de Calvin

0

C # - 134

Bem, eu postei uma resposta aqui antes, mas não era tão sério assim. Por acaso, muitas vezes estou muito entediado, então joguei um pouco de golfe.

Ele calcula todos os exemplos tecnicamente corretamente (não tentei os dois últimos porque, novamente, a ideona impõe um limite de tempo de 5 segundos), mas os primeiros produzem o resultado correto (não necessariamente o resultado que você calculou, mas o correto). É estranhamente emite o número fora de ordem (não tenho idéia por que) e dá 10, 5, 2para 5(que é uma resposta válida de acordo com a wikipedia).

134 bytes por enquanto, eu provavelmente poderia aumentar um pouco mais.

float[]f(float n){float x=1,y,z;for(;x<1<<30;x++)for(y=1;y<x;y++)for(z=1;z<y;z++)if(4/n==1/x+1/y+1/z)return new[]{x,y,z};return null;}

0

Haskell - 150 caracteres

main = getLine >>= \n -> (return $ head $ [(x,y,z) | x <- [1..y], y <- [1..z], z <- [1..], (4/n') == (1/x) + (1/y) + (1/z)]) where n' = read n

Isso deve funcionar, mas ainda não o compilei. É quase certamente muito, muito lento. Ele verifica todos os trigêmeos possíveis de inteiros válidos e deve parar quando vir um conjunto que funcione.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.