Erd –s-Straus varsayımını doğrulayan yazma programı


15

Erd –s-Straus varsayımını doğrulayan program yaz .
Program girdi olarak bir tamsayı almalı n( 3 <= n <= 1 000 000) ve kimliğini tatmin tamsayılar üçlü baskı 4/n = 1/x + 1/y + 1/z, 0 < x < y < z.

En kısa kod kazanır.

Bazı örnekler:

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

Birden fazla çözüm olduğu için programınızın bu sayılar için başka sonuçlar yazdırabileceğini unutmayın.


Programın mümkün olan her çözümü mi yoksa yalnızca birini mi alması gerekiyor? Örneğin n = 5 için 2 olasılık vardır.
izlin

1
Sadece bir tane yeter.
Somnium

2
Tek test durumunuzun spesifikasyona göre geçerli bir giriş olmaması biraz yanıltıcıdır.
Peter Taylor

Değiştireceğim, örnek durron597 ekledi.
Somnium

Bu örneği de ekledim, çünkü araştırmamın yapılması özellikle zor bir şeydi. En zor olanlar {1, 121, 169, 289, 361, 529}modulo 840 ile uyumlu olan
asallardır.

Yanıtlar:


12

Ruby, 119106 karakter

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

Kod, her değişken için minimum sınırlar kullanır, örneğin n/4<x<3n/4, benzer şekilde y. Son örnek bile anında geri döner ( burada deneyin ).

Örnekler:

> 12
[4, 13, 156]

> 123
[31, 3814, 14542782]

> 1234
[309, 190654, 36348757062]

> 40881241801
[10220310451, 139272994276206121600, 22828913614743204775214996005450198400]

Serin çözüm, ancak sınırlar biraz sıkı, çünkü 1000 000 için programınız daha büyük bir çözüm bulur (örneğime bakın).
Somnium

1
@ user2992539 Kodum sözlükbilimsel olarak ilk çözümü döndürür (250001 <500000).
Howard

7

Mathematica 62

Bu düz vanilya çözümü çoğu zaman iyi çalışır.

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

Örnekler ve Zamanlamalar (saniye cinsinden)

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


Ancak tam bir çözüm oluşturmaz. Çözemediği bazı sayılar var. Örneğin,

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

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


Doğru iş için doğru araç. +1
William Barbosa

3
@WilliamBarbosa FindInstanceBir sonucu garanti edemeyeceği için doğru araç olmadığını iddia ediyorum ...
Howard

2
@ Mathematica hakkında konuşuyordum, aslında
William Barbosa

Reduceinatçı vakaları çözüyor gibi görünse de, çoğu zaman zaman alır. N = 10037 için 82 çözelti bulmak için 15 dakika.
DavidC

3

C #

Feragatname: Bu ciddi bir cevap değil

Bu sadece 1'den 1'e kadar tüm olasılıkları güçlendirir << 30. Çok büyük, yavaş, düzgün çalışıp çalışmadığını bile bilmiyorum, ancak her defasında durumu kontrol ettiği için özellikleri tam anlamıyla takip ediyor, bu güzel. Bunu test etmedim çünkü ideone'nin programlar için 5 saniyelik bir sınırı vardır ve bu nedenle yürütme işlemi bitmez.

(Herkesin merak etmesi durumunda: bu 308 bayt uzunluğunda)

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

Güncelleme: düzeltildi, böylece gerçekten çalışıyor


2
Çalışmıyor (ipucu: tamsayı bölümü).
Howard

Büyük olasılıkla yuvarlama hataları nedeniyle çalışmaz.
Somnium

@ user2992539 benim için çalışıyor, 5girdi olarak test ettim ve doğru sonucu verdi ( 2, 4, 20)
Christoph Böhmwalder

@HackerCow büyük tamsayılar için çalışmayabilir.
Somnium

1
@HackerCow, y = x + 1 ve z = y + 1 ile başlayarak zaman kazanabilirsiniz. Muhtemelen daha uzun bir ifade olduğunu ve yuvarlama sorunları olduğunu kabul etsem de eşdeğer kontrol 4xyz = n (xy + yz + xz) kullanmak daha hızlı olacaktır.
Simyacı

3

Python 2 , 171 bayt

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

Çevrimiçi deneyin!

İlk cevap, kapsamlı bir şekilde test edilecek kadar hızlı. Bu, her biri ortalama 1.4 milisaniye olmak üzere , toplam yaklaşık 24 dakikada 3 ≤ n ≤ 1000000 için çözümler bulabilir .

Nasıl çalışır

4 / yeniden yazma n = 1 / x + 1 / y + 1 / z olarak Z = N · x · y / d , d = 4 · x · y - N · X - N · y . Sonra 4 · d + n 2 = (4 · x - n ) · (4 · y - n ) bize çok daha hızlı aramak için yol verir, x ve y uzun olduğunca dküçük. X < y < z göz önüne alındığında , en azından d <3 · n 2 / 4'ü (dolayısıyla dış halkadaki bağ) kanıtlayabiliriz , ancak pratikte çok daha küçük olma eğilimindedir - zamanın% 95'i, d = 1, 2 veya 3. En kötü durum n = 769129'dur, bunun için en küçük d 1754'tür (bu durum yaklaşık 1 saniye sürer).


1

Mathematica, 99 bayt

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

Oldukça saf kaba kuvvet, bu yüzden gerçekten iyi ölçeklenmiyor. Kesinlikle bir milyona gideceğim (şu an için bu geçersiz olduğunu düşünmekten çekinmeyin). n = 100yarım n = 300saniye sürer , ancak zaten 12 saniye sürer.


1

Golflua 75

İstemden okur n(terminalde çağrıldıktan sonra), ancak temel olarak Calvin'in Hobbies çözümünün yaptığı gibi tekrarlar :

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$

Yukarıdakilerin ungolfed Lua versiyonu

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

Örnekler:

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

Misal:

16 --> 10 12 15

Çok özel bir şey yok.


1
Bir işlevi yalnızca bir kez arayacaksanız neden bir işlev tanımlıyorsunuz?
isaacg

@isaacg Bir şekilde durması gerekiyor, ancak exit()bunun yerine kullanılması onu kısaltıyor .
Calvin'in Hobileri

0

C # - 134

Daha önce burada bir cevap gönderdim, ama bu o kadar da ciddi değildi. Olduğu gibi, çok sıkıldım, bu yüzden biraz golf oynadım.

Tüm örnekleri teknik olarak doğru bir şekilde hesaplar (son ikisini denemedim, çünkü yine, ideone 5 saniyelik bir zaman sınırını uygular), ancak ilki doğru sonucu verir (mutlaka hesapladığınız sonucu değil, doğru olanı). Bu garip bozuk sayısını verir (neden hiçbir ipucu var) ve o verir 10, 5, 2için 5(wikipedia göre geçerli bir cevap olan).

Şimdilik 134 bayt, muhtemelen biraz daha golf olabilir.

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 karakter

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

Bu işe yaramalı, ama henüz derlemedim. Neredeyse kesinlikle çok çok yavaş. Geçerli tamsayıların her üçlüsünü kontrol eder ve çalışan bir küme gördüğünde durmalıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.