Menulis program yang memverifikasi dugaan Erd-Straus


15

Menulis program, yang memverifikasi dugaan Erd-Straus .
Program harus mengambil sebagai masukan satu bilangan bulat n( 3 <= n <= 1 000 000) dan mencetak tiga bilangan bulat memuaskan identitas 4/n = 1/x + 1/y + 1/z, 0 < x < y < z.

Kode terpendek menang.

Beberapa contoh:

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

Perhatikan bahwa program Anda dapat mencetak hasil lain untuk nomor-nomor ini karena ada beberapa solusi.


Apakah program perlu menampilkan setiap solusi yang mungkin atau hanya satu? Misalnya ada 2 kemungkinan untuk n = 5.
izlin

1
Hanya satu yang cukup.
Somnium

2
Agak menyesatkan bahwa satu-satunya test case Anda bukan input yang valid sesuai dengan spesifikasi.
Peter Taylor

Saya akan mengubahnya, contohnya ditambahkan durron597.
Somnium

Saya menambahkan contoh itu karena penelitian saya menyarankan itu yang sangat sulit dilakukan. Yang paling sulit adalah bilangan prima yang kongruen dengan {1, 121, 169, 289, 361, 529}modulo 840.
durron597

Jawaban:


12

Ruby, 119 106 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,[]]

Kode menggunakan batas minimal untuk setiap variabel, misalnya n/4<x<3n/4, sama untuk y. Bahkan contoh terakhir mengembalikan seketika (coba di sini ).

Contoh:

> 12
[4, 13, 156]

> 123
[31, 3814, 14542782]

> 1234
[309, 190654, 36348757062]

> 40881241801
[10220310451, 139272994276206121600, 22828913614743204775214996005450198400]

Solusi keren, namun batasannya sedikit ketat, karena program Anda untuk 1.000 000 menemukan solusi yang lebih besar (lihat contoh saya).
Somnium

1
@ user2992539 Kode saya mengembalikan solusi leksikografis pertama (250001 <500000).
Howard

7

Mathematica 62

Solusi vanilla polos ini berfungsi dengan baik - sebagian besar waktu.

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

Contoh dan Pengaturan Waktu (dalam detik)

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


Tetapi itu bukan merupakan solusi yang lengkap. Ada beberapa angka yang tidak bisa dipecahkan. Sebagai contoh,

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

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


Alat yang tepat untuk pekerjaan yang tepat. +1
William Barbosa

3
@ WilliamBarbosa Saya berpendapat bahwa FindInstanceitu bukan alat yang tepat karena tidak dapat menjamin hasilnya ...
Howard

2
@ Bagaimana saya berbicara tentang Mathematica, sebenarnya
William Barbosa

Reducetampaknya menyelesaikan kasus-kasus yang membandel, meskipun seringkali membutuhkan waktu. Misalnya 15 menit untuk menemukan 82 solusi untuk n = 10037.
DavidC

3

C #

Disclamer: ini bukan jawaban yang serius

Ini hanya memperkuat semua kemungkinan dari 1 hingga 1 << 30. Ini besar, lambat, saya bahkan tidak tahu apakah itu berfungsi dengan benar, tetapi mengikuti spesifikasi secara harfiah, karena memeriksa kondisi setiap saat, jadi itu bagus. Saya belum menguji ini karena ideone memiliki batas waktu 5 detik untuk program dan karenanya ini tidak akan selesai dijalankan.

(Seandainya ada yang bertanya-tanya: panjangnya 308 byte )

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

Perbarui: perbaiki agar benar-benar berfungsi


2
Tidak berfungsi (petunjuk: pembagian integer).
Howard

Kemungkinan itu tidak akan berhasil karena kesalahan pembulatan.
Somnium

@ user2992539 berfungsi untuk saya, saya mengujinya dengan 5masukan dan memberikan hasil yang benar ( 2, 4, 20)
Christoph Böhmwalder

@ HackerCow mungkin tidak bekerja untuk bilangan bulat besar.
Somnium

1
@HackerCow Anda tentu dapat menghemat waktu dengan memulai dengan y = x + 1 dan z = y + 1. Mungkin akan lebih cepat menggunakan cek setara 4xyz = n (xy + yz + xz), meskipun saya menerima bahwa ini adalah ekspresi yang lebih panjang dan juga memiliki masalah pembulatan.
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

Cobalah online!

Jawaban pertama cukup cepat untuk diuji secara mendalam. Ini dapat menemukan solusi untuk semua 3 ≤ n ≤ 1000000 dalam total sekitar 24 menit , dengan rata-rata sekitar 1,4 milidetik masing-masing.

Bagaimana itu bekerja

Tulis ulang 4 / n = 1 / x + 1 / y + 1 / z sebagai z = n · x · y / d , di mana d = 4 · x · y - n · x - n · y . Maka kita dapat faktor 4 · d + n 2 = (4 · x - n ) · (4 · y - n ), yang memberi kita cara yang jauh lebih cepat untuk mencari x dan y selama d kecil. Diberikan x< Y < z , setidaknya kita dapat membuktikan d <3 · n 2 /4 (maka terikat pada lingkaran luar), meskipun dalam prakteknya cenderung jauh lebih kecil-95% dari waktu, kita dapat menggunakan d = 1 , 2, atau 3. Kasing terburuk adalah n = 769129, dengan yang terkecil d adalah 1754 ( kasing ini memakan waktu sekitar 1 detik).


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

Ini kekuatan kasar yang cukup naif, sehingga tidak benar-benar berskala baik. Saya pasti akan mendapatkan satu juta (jadi silakan menganggap ini tidak valid untuk saat ini). n = 100membutuhkan setengah detik, tetapi n = 300sudah membutuhkan 12 detik.


1

Golflua 75

Dibaca ndari prompt (setelah doa di terminal), tetapi pada dasarnya iterates sebagai solusi Calvin Hobbies tidak:

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$

Versi Lua ungolfed dari di atas adalah

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

Contoh:

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

Contoh:

16 --> 10 12 15

Tidak ada yang terlalu istimewa.


1
Mengapa Anda mendefinisikan suatu fungsi jika Anda hanya akan memanggilnya sekali?
isaacg

@isaacg Ini perlu dihentikan, tetapi menggunakannya exit()bukan mempersingkatnya.
Hobi Calvin

0

C # - 134

Yah, saya mengirim jawaban di sini sebelumnya, tapi itu tidak terlalu serius. Ketika hal itu terjadi, saya sangat sering merasa bosan, jadi saya bermain golf sedikit.

Ini menghitung semua contoh secara teknis dengan benar (saya belum mencoba dua yang terakhir karena, sekali lagi, ideone memberikan batas waktu 5 detik) tetapi yang pertama menghasilkan hasil yang benar (tidak harus hasil yang Anda hitung, tetapi yang benar). Ini aneh output jumlah dari urutan (saya tidak tahu mengapa) dan memberikan 10, 5, 2untuk 5(yang merupakan jawaban yang valid menurut wikipedia).

134 byte untuk saat ini, saya mungkin bisa sedikit lebih golf.

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

Ini seharusnya berhasil, tetapi saya belum mengkompilasinya. Hampir pasti sangat lambat. Ia memeriksa setiap triplet yang mungkin dari bilangan bulat yang valid, dan harus berhenti ketika melihat himpunan yang berfungsi.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.