Programa de escritura que verifica la conjetura de Erdős-Straus


15

Programa de escritura, que verifica la conjetura de Erdős-Straus .
Programa debe tener como entrada un entero n( 3 <= n <= 1 000 000) e imprimir el triple de números enteros que satisfacen la identidad 4/n = 1/x + 1/y + 1/z, 0 < x < y < z.

El código más corto gana.

Algunos ejemplos:

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

Tenga en cuenta que su programa puede imprimir otros resultados para estos números porque hay múltiples soluciones.


¿El programa necesita generar todas las soluciones posibles o solo una? Por ejemplo, hay 2 posibilidades para n = 5.
izlin

1
Solo uno es suficiente.
Somnium

2
Es un tanto engañoso que su único caso de prueba no sea una entrada válida de acuerdo con las especificaciones.
Peter Taylor

Lo cambiaré, ejemplo añadido durron597.
Somnium

Agregué ese ejemplo porque mi investigación sugirió que era particularmente difícil de hacer. Los más difíciles son números primos que son congruentes con el {1, 121, 169, 289, 361, 529}módulo 840.
durron597

Respuestas:


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,[]]

El código usa límites mínimos para cada variable, por ejemplo n/4<x<3n/4, de manera similar para y. Incluso el último ejemplo devuelve instantáneo (intente aquí ).

Ejemplos:

> 12
[4, 13, 156]

> 123
[31, 3814, 14542782]

> 1234
[309, 190654, 36348757062]

> 40881241801
[10220310451, 139272994276206121600, 22828913614743204775214996005450198400]

Solución genial, sin embargo, los límites son un poco ajustados, porque su programa para 1 000 000 encuentra una solución mayor (vea mi ejemplo).
Somnium

1
@ user2992539 Mi código devuelve la primera solución lexicográfica (250001 <500000).
Howard

7

Mathematica 62

Esta solución simple de vainilla funciona bien, la mayoría de las veces.

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

Ejemplos y tiempos (en 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}}}


Pero no constituye una solución completa. Hay algunos números que no puede resolver. Por ejemplo,

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

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


La herramienta adecuada para el trabajo correcto. +1
William Barbosa

3
@WilliamBarbosa Yo diría que FindInstanceno es la herramienta correcta ya que no puede garantizar un resultado ...
Howard

2
@Howard Estaba hablando de Mathematica, en realidad
William Barbosa

Reduceparece resolver los casos obstinados, aunque a menudo lleva tiempo. Por ejemplo, 15 minutos para encontrar 82 soluciones para n = 10037.
DavidC

3

C#

Descargo de responsabilidad: esta no es una respuesta seria

Esto simplemente aplica todas las posibilidades de 1 a 1 << 30. Es enorme, es lento, ni siquiera sé si funciona correctamente, pero sigue las especificaciones literalmente, ya que comprueba la condición cada vez, así que eso es bueno. No he probado esto porque ideone tiene un límite de tiempo de 5 segundos para los programas y, por lo tanto, esto no terminará de ejecutarse.

(En caso de que alguien se preguntara: esta es la friolera 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;
}

Actualización: lo arregló para que realmente funcione


2
No funciona (pista: división entera).
Howard

Probablemente no funcionará debido a errores de redondeo.
Somnium

@ user2992539 funciona para mí, lo probé 5como entrada y me dio el resultado correcto ( 2, 4, 20)
Christoph Böhmwalder

@HackerCow puede no funcionar para enteros grandes.
Somnium

1
@HackerCow ciertamente puede ahorrar tiempo al comenzar con y = x + 1 y z = y + 1. Probablemente será más rápido usar la verificación equivalente 4xyz = n (xy + yz + xz), aunque acepto que es una expresión más larga y también tiene problemas de redondeo.
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

Pruébalo en línea!

La primera respuesta es lo suficientemente rápida como para ser probada exhaustivamente. Esto es capaz de encontrar soluciones para los 3 ≤ n ≤ 1000000 en aproximadamente 24 minutos en total , para un promedio de aproximadamente 1.4 milisegundos cada uno.

Cómo funciona

Reescribe 4 / n = 1 / x + 1 / y + 1 / z como z = n · x · y / d , donde d = 4 · x · y - n · x - n · y . Entonces podemos factorizar 4 · d + n 2 = (4 · x - n ) · (4 · y - n ), lo que nos da una forma mucho más rápida de buscar x e y siempre que des pequeño. Dadas x < y < z , podemos al menos demostrar d <3 · n 2 /4 (de ahí el ligado en el bucle externo), aunque en la práctica tiende a ser mucho más pequeño-95% del tiempo, podemos utilizar d = 1, 2 o 3. El peor de los casos es n = 769129, para el cual el d más pequeño es 1754 (este caso toma aproximadamente 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])

Es una fuerza bruta bastante ingenua, por lo que realmente no escala bien. Definitivamente voy a llegar a un millón (así que siéntase libre de considerar esto inválido por el momento). n = 100toma medio segundo, pero n = 300ya lleva 12 segundos.


1

Golflua 75

Lee ndesde el indicador (después de la invocación en la terminal), pero básicamente itera como lo hace la solución de Calvin's Hobbies :

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$

Una versión sin Lua de lo anterior es

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

Ejemplos:

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()

Ejemplo:

16 --> 10 12 15

Nada muy especial


1
¿Por qué define una función si solo la va a llamar una vez?
isaacg

@isaacg Debe detenerse de alguna manera, pero usarlo en exit()cambio lo acorta.
Aficiones de Calvin

0

C # - 134

Bueno, publiqué una respuesta aquí antes, pero en realidad no fue tan grave. Como sucede, a menudo estoy muy aburrido, así que jugué un poco al golf.

Calcula todos los ejemplos técnicamente correctamente (no he probado los dos últimos porque, de nuevo, ideone informa un límite de tiempo de 5 segundos) pero los primeros arrojan el resultado correcto (no necesariamente el resultado que calculó, sino uno correcto). Extrañamente saca el número fuera de servicio (no tengo idea de por qué) y da 10, 5, 2por 5(que es una respuesta válida de acuerdo con wikipedia).

134 bytes por ahora, probablemente podría jugar un poco más.

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

Esto debería funcionar, pero aún no lo he compilado. Es casi seguro que es muy, muy lento. Comprueba cada triplete posible de enteros válidos, y debe detenerse cuando ve un conjunto que funciona.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.