Schreiben Sie ein Programm, das die Erdős-Straus-Vermutung bestätigt


15

Schreiben Sie ein Programm, das die Erdős-Straus-Vermutung bestätigt .
Programm sollte als Eingabe eine ganze Zahl nehmen n( 3 <= n <= 1 000 000) und dreifache der ganzen Zahlen drucken Identität erfüllt 4/n = 1/x + 1/y + 1/z, 0 < x < y < z.

Kürzester Code gewinnt.

Einige Beispiele:

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

Beachten Sie, dass Ihr Programm möglicherweise andere Ergebnisse für diese Zahlen ausgibt, da es mehrere Lösungen gibt.


Muss das Programm jede mögliche Lösung ausgeben oder nur eine? Zum Beispiel gibt es 2 Möglichkeiten für n = 5.
Izlin

1
Nur einer ist genug.
Somnium

2
Es ist etwas irreführend, dass Ihr einziger Testfall keine gültige Eingabe gemäß der Spezifikation ist.
Peter Taylor

Ich werde es ändern, Beispiel hinzugefügt Durron597.
Somnium

Ich fügte dieses Beispiel hinzu, weil meine Recherchen ergaben, dass es besonders schwierig war. Die schwierigsten sind Primzahlen, die für {1, 121, 169, 289, 361, 529}Modulo 840 kongruent sind.
Durron597

Antworten:


12

Ruby, 119 106 Zeichen

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

Der Code verwendet minimale Grenzen für jede Variable, z . B. n/4<x<3n/4ähnlich für y. Sogar das letzte Beispiel gibt sofort zurück (versuchen Sie es hier ).

Beispiele:

> 12
[4, 13, 156]

> 123
[31, 3814, 14542782]

> 1234
[309, 190654, 36348757062]

> 40881241801
[10220310451, 139272994276206121600, 22828913614743204775214996005450198400]

Coole Lösung, allerdings sind die Grenzen etwas eng, weil Ihr Programm für 1 000 000 eine bessere Lösung findet (siehe mein Beispiel).
Somnium

1
@ user2992539 Mein Code gibt die lexikografisch erste Lösung zurück (250001 <500000).
Howard

7

Mathematica 62

Diese Vanille-Lösung funktioniert meistens einwandfrei.

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

Beispiele und Timings (in Sekunden)

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


Es handelt sich jedoch nicht um eine vollständige Lösung. Es gibt einige Zahlen, für die es keine Lösung gibt. Beispielsweise,

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

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


Das richtige Werkzeug für den richtigen Job. +1
William Barbosa

3
@ WilliamBarbosa Ich würde argumentieren, dass FindInstancedas nicht das richtige Werkzeug ist, da es kein Ergebnis garantieren kann ...
Howard

2
@ Howard Ich sprach über Mathematica, eigentlich
William Barbosa

Reducescheint die hartnäckigen Fälle zu lösen, obwohl es oft Zeit braucht. ZB 15 Minuten, um 82 Lösungen für n = 10037 zu finden.
DavidC

3

C #

Disclamer: Dies ist keine ernsthafte Antwort

Dies erzwingt alle Möglichkeiten von 1 bis 1 << 30. Es ist riesig, es ist langsam, ich weiß nicht einmal, ob es richtig funktioniert, aber es folgt buchstäblich den Spezifikationen, da es den Zustand jedes Mal überprüft, also ist das schön. Ich habe dies nicht getestet, da ideone ein Zeitlimit von 5 Sekunden für Programme hat und daher die Ausführung nicht beendet wird.

(Für den Fall, dass sich jemand wundert: das sind satte 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;
}

Update: behoben, so dass es tatsächlich funktioniert


2
Funktioniert nicht (Hinweis: Ganzzahldivision).
Howard

Wahrscheinlich wird es wegen Abrundungsfehlern nicht funktionieren.
Somnium

@ user2992539 es funktioniert für mich, ich habe es mit 5als Eingabe getestet und es gab das richtige Ergebnis ( 2, 4, 20)
Christoph Böhmwalder

@ HackerCow funktioniert möglicherweise nicht für große ganze Zahlen.
Somnium

1
@HackerCow Sie können sicherlich Zeit sparen, indem Sie mit y = x + 1 und z = y + 1 beginnen. Es wird wahrscheinlich schneller sein, das äquivalente Häkchen 4xyz = n (xy + yz + xz) zu verwenden, obwohl ich akzeptiere, dass dies ein längerer Ausdruck ist und auch Rundungsprobleme hat.
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

Probieren Sie es online!

Die erste Antwort ist schnell genug, um ausführlich getestet zu werden. Dies ist in der Lage , Lösungen zu finden für alle 3 ≤ n ≤ 1000000 in etwa 24 Minuten betragen , bei einem Durchschnitt von etwa 1,4 Millisekunden je.

Wie es funktioniert

Schreibe 4 / n = 1 / x + 1 / y + 1 / z um als z = n · x · y / d , wobei d = 4 · x · y - n · x - n · y . Dann können wir 4 · d + n 2 = (4 · x - n ) · (4 · y - n ) faktorisieren , was uns einen viel schnelleren Weg gibt, nach x und y zu suchen, solange d giltist klein. Gegeben x < y < z , kann man zumindest beweisen d <3 · n 2 /4 (also der gebundene an der äußeren Schleife), obwohl es in der Praxis viel kleiner-95% der Zeit tendenziell zu, kann man verwenden , d = 1, 2 oder 3. Der schlechteste Fall ist n = 769129, für den das kleinste d 1754 ist (dieser Fall dauert ungefähr 1 Sekunde).


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 ist ziemlich naive Brute Force, also lässt es sich nicht wirklich gut skalieren. Ich werde definitiv eine Million erreichen (zögern Sie also nicht, dies vorerst für ungültig zu erklären). n = 100dauert eine halbe Sekunde, n = 300dauert aber schon 12 Sekunden.


1

Golflua 75

Liest nvon der Eingabeaufforderung aus (nach dem Aufruf im Terminal), iteriert jedoch im Grunde genommen wie Calvins Hobbies- Lösung:

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$

Eine ungolfed Lua Version von oben ist

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

Beispiele:

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

Beispiel:

16 --> 10 12 15

Nichts zu spezielles.


1
Warum definieren Sie eine Funktion, wenn Sie sie nur einmal aufrufen möchten?
isaacg

@isaacg Es muss irgendwie aufhören, aber die Verwendung von exit()verkürzt es.
Calvins Hobbys

0

C # - 134

Nun, ich habe hier schon eine Antwort gepostet, aber es war nicht wirklich so ernst. Wie es so kommt, langweile ich mich sehr oft und habe ein bisschen Golf gespielt.

Es berechnet alle Beispiele technisch korrekt (ich habe die letzten beiden nicht ausprobiert, da ideone wiederum ein Zeitlimit von 5 Sekunden vorschreibt), aber die ersten liefern das korrekte Ergebnis (nicht unbedingt das von Ihnen berechnete, sondern ein korrektes Ergebnis). Es gibt seltsamerweise die Nummer in der falschen Reihenfolge aus (ich habe keine Ahnung warum) und es gibt 10, 5, 2für 5(was laut Wikipedia eine gültige Antwort ist).

134 Bytes für den Moment, ich könnte wahrscheinlich ein bisschen mehr Golf spielen.

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 Zeichen

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

Das sollte funktionieren, aber ich habe es noch nicht kompiliert. Es ist mit ziemlicher Sicherheit sehr sehr langsam. Es überprüft jedes mögliche Triplett gültiger Ganzzahlen und sollte anhalten, wenn ein Satz angezeigt wird, der funktioniert.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.