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.