Scrivi un programma che verifica la congettura di Erdős – Straus


15

Scrivi programma, che verifica la congettura di Erdős – Straus .
Programma dovrebbe prendere in input un intero n( 3 <= n <= 1 000 000) e stampare triple di interi che soddisfano l'identità 4/n = 1/x + 1/y + 1/z, 0 < x < y < z.

Il codice più corto vince.

Qualche esempio:

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

Si noti che il programma potrebbe stampare altri risultati per questi numeri perché esistono più soluzioni.


Il programma deve produrre tutte le possibili soluzioni o solo una? Ad esempio ci sono 2 possibilità per n = 5.
izlin,

1
Ne basta uno solo.
Somnium,

2
È in qualche modo fuorviante che il tuo unico test case non sia un input valido secondo le specifiche.
Peter Taylor,

Lo cambierò, esempio aggiunto durron597.
Somnium,

Ho aggiunto questo esempio perché la mia ricerca mi ha suggerito che era particolarmente difficile da fare. I più difficili sono numeri primi che sono congruenti con il {1, 121, 169, 289, 361, 529}modulo 840.
durron597

Risposte:


12

Rubino, 119 106 caratteri

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

Il codice utilizza limiti minimi per ogni variabile, ad esempio in n/4<x<3n/4modo simile per y. Anche l'ultimo esempio restituisce istantaneo (prova qui ).

Esempi:

> 12
[4, 13, 156]

> 123
[31, 3814, 14542782]

> 1234
[309, 190654, 36348757062]

> 40881241801
[10220310451, 139272994276206121600, 22828913614743204775214996005450198400]

Soluzione interessante, tuttavia i limiti sono un po 'stretti, perché il tuo programma per 1 000 000 trova una soluzione migliore (vedi il mio esempio).
Somnium,

1
@ user2992539 Il mio codice restituisce la prima soluzione lessicografa (250001 <500000).
Howard,

7

Mathematica 62

Questa soluzione semplice alla vaniglia funziona bene, il più delle volte.

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

Esempi e tempi (in secondi)

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}}}


Ma non costituisce una soluzione completa. Ci sono alcuni numeri che non è possibile risolvere. Per esempio,

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

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


Lo strumento giusto per il lavoro giusto. +1
William Barbosa,

3
@WilliamBarbosa Direi che FindInstancenon è lo strumento giusto poiché non può garantire un risultato ...
Howard,

2
@Howard stavo parlando di Mathematica, in realtà
William Barbosa,

Reducesembra risolvere i casi testardi, anche se spesso ci vuole tempo. Ad esempio 15 minuti per trovare 82 soluzioni per n = 10037.
DavidC,

3

C #

Disclamer: questa non è una risposta seria

Questo bruta forza tutte le possibilità da 1 a 1 << 30. È enorme, è lento, non so nemmeno se funziona correttamente, ma segue le specifiche letteralmente, poiché controlla le condizioni ogni volta, quindi è carino. Non l'ho provato perché ideone ha un limite di tempo di 5 secondi per i programmi e quindi questo non finirà di essere eseguito.

(Nel caso qualcuno si chiedesse: questo è un enorme 308 byte di lunghezza)

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;
}

Aggiornamento: risolto in modo che funzioni davvero


2
Non funziona (suggerimento: divisione intera).
Howard,

Probabilmente non funzionerà a causa di errori di arrotondamento.
Somnium,

@ user2992539 funziona per me, l'ho provato 5come input e ha dato il risultato corretto ( 2, 4, 20)
Christoph Böhmwalder

@HackerCow potrebbe non funzionare con numeri interi grandi.
Somnium,

1
@HackerCow puoi sicuramente risparmiare tempo iniziando con y = x + 1 e z = y + 1. Probabilmente sarà più veloce usare il controllo equivalente 4xyz = n (xy + yz + xz), anche se accetto che sia un'espressione più lunga e abbia anche problemi di arrotondamento.
Alchymist,

3

Python 2 , 171 byte

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

Provalo online!

La prima risposta abbastanza veloce per essere testata in modo esauriente. Questo è in grado di trovare soluzioni per tutti i 3 ≤ n ≤ 1000000 in circa 24 minuti totali , per una media di circa 1,4 millisecondi ciascuno.

Come funziona

Riscrivi 4 / n = 1 / x + 1 / y + 1 / z come z = n · x · y / d , dove d = 4 · x · y - n · x - n · y . Quindi possiamo fattorizzare 4 · d + n 2 = (4 · x - n ) · (4 · y - n ), che ci dà un modo molto più veloce di cercare x ed è piccolo. Dato x y finché d < y < z , possiamo almeno provare d <3 · n 2 /4 (da qui la vincolato sul ciclo esterno), anche se in pratica si tende ad essere molto più piccolo-95% del tempo, possiamo usare d = 1, 2 o 3. Il caso peggiore è n = 769129, per cui la più piccola d è 1754 (questo caso richiede circa 1 secondo).


1

Mathematica, 99 byte

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

È una forza bruta abbastanza ingenua, quindi non si adatta bene. Arriverò sicuramente a un milione (quindi sentiti libero di considerare questo non valido per il momento). n = 100richiede mezzo secondo, ma n = 300richiede già 12 secondi.


1

Golflua 75

Legge ndal prompt (dopo l'invocazione nel terminale), ma sostanzialmente ripete come la soluzione Hobbies di Calvin :

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 versione non giocata di Lua di cui sopra è

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

Esempi:

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

Esempio:

16 --> 10 12 15

Niente di speciale.


1
Perché definisci una funzione se la chiamerai solo una volta?
Isaacg,

@isaacg Deve smettere in qualche modo, ma usare exit()invece lo accorcia.
Calvin's Hobbies,

0

C # - 134

Bene, ho pubblicato una risposta qui prima, ma non era poi così grave. In questo caso, molto spesso sono molto annoiato, quindi ho giocato un po 'a golf.

Calcola tecnicamente tutti gli esempi correttamente (non ho provato gli ultimi due perché, ancora una volta, ideone applica un limite di tempo di 5 secondi) ma i primi danno il risultato corretto (non necessariamente il risultato che hai calcolato, ma uno corretto). Emette stranamente il numero fuori servizio (non ho idea del perché) e dà 10, 5, 2per 5(che è una risposta valida secondo Wikipedia).

134 byte per ora, probabilmente potrei giocarci un po 'di più.

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 caratteri

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

Questo dovrebbe funzionare, ma non l'ho ancora compilato. È quasi certamente molto molto lento. Controlla ogni possibile tripletta di numeri interi validi e dovrebbe arrestarsi quando vede un set che funziona.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.