Masalahnya adalah sebagai berikut.
Input: Bilangan bulatn
Output: Perdana terkecil lebih besar dari n
.
Tantangannya adalah untuk memberikan kode tercepat yang dapat dilakukan. Saya akan menguji kode pada nilai mulai dari ukuran kira 10^8
10^200
- kira dan menggandakan ukuran sampai dibutuhkan lebih dari satu menit 10 detik di komputer saya.
Kode yang menang akan menemukan perdana berikutnya untuk ukuran input terbesar.
Sebagai perbandingan, saringan sederhana yang ditulis dengan python mampu menemukan perdana berikutnya yang lebih besar dari 10^8
pada sekitar20
hitungan detik.
Persyaratan bahwa saya dapat mengujinya pada komputer ubuntu RAM 4GB saya sangat ketat. Semua kode harus gratis (dalam kedua pengertian) dan jika menggunakan pustaka mereka juga harus bebas dan mudah diinstal. Setiap bilangan prima yang dilaporkan akan segera mendiskualifikasi pengajuan.
Saya akan memberikan pujian terpisah untuk pemenang dalam setiap bahasa pemrograman juga jika kode sepenuhnya ditulis dalam bahasa itu tanpa menggunakan perpustakaan eksternal. Saya juga akan membuat tabel berjalan dari waktu tercepat saat kompetisi berlangsung sehingga orang dapat melihat bagaimana kinerja mereka.
Meja sejauh ini
- Python.
357
Digit prima yang menakjubkan343239883006530485749095039954069660863471765007165270469723172959277159169882802606127982033072727748864815569574042901856099399985832190628701414555752857600000000000000000000000000000000000000002872284792758930912601189043411951050852357613658978971208596097634095500808832510259693761982135208603287199546795000697807728609476163156438356035166156820611
adalah angka terakhir di bawah 10 detik menggunakan kode yang disediakan olehprimo
. Adakah yang akan mengalahkan entri pertama ini?
sumber
fast next prime function
juga.Jawaban:
Python ~ 451 digit
Ini adalah bagian dari perpustakaan yang saya tulis untuk masalah faktorisasi semiprime , dengan fungsi yang tidak perlu dihapus. Ia menggunakan tes primality Baillie-PSW , yang secara teknis merupakan tes probabilistik, tetapi hingga saat ini, tidak ada pseudoprim yang diketahui - dan bahkan ada hadiah uang tunai jika Anda dapat menemukannya (atau untuk memberikan bukti bahwa tidak ada) .
Sunting : Saya tidak menyadari bahwa Python memiliki eksponensial modular bawaan. Mengganti sendiri untuk hasil bawaan menghasilkan peningkatan kinerja sekitar 33%.
my_math.py
Contoh skrip uji:
Faktor 317 dipilih, karena kira-kira akar kuadratnya
10000
, menambahkan sekitar 2,5 digit per iterasi (dan karena penggandaan terlalu lambat untuk diduduki). Output menunjukkan jumlah digit saat ini, dan waktu yang dibutuhkan.Hasil sampel:
Semua kode sekarang kompatibel dengan python.
sumber
next_prime((2^520)*(10^200))
sekitar 15 detik di komputer saya, jadi pada blush on pertama ini cukup mengesankan. Namun ...next_prime((2^520)*(10^200),proof=False)
butuh 0,4 detik karena hanya memeriksa pseudoprimality. Klaim Anda "tidak ada pseudoprim yang diketahui" menghilang dengan meyakinkan karena jumlah bit lebih dari 64. Untuk 357 digit, saya bahkan tidak terlalu diyakinkan oleh kurangnya contoh tandingan.C ++ dengan GMP: 567 digit
Menggunakan implementasi Miller-Rabin di GMP. Ini mungkin mengembalikan positif palsu, tetapi keberuntungan benar-benar memukul seseorang dengan probabilitas 2 ^ -200.
Menemukan yang terbaik
10^200 * 2^1216 + 361
(567 digit) sebelum berjalan dari waktu ke waktu di laptop lambat saya.sumber
Perl dengan modul GMP, 1300 digit
Menggunakan modul saya Math :: Prime :: Util dan bagian belakang GMP -nya . Titik potong yang tepat akan tergantung pada komputer Anda dan apakah Anda memiliki perpustakaan GMP terbaru. Semua kode gratis (modul-modulnya ada di github dan CPAN, dan GMP tersedia secara bebas). Saya sudah menjalankannya di AWS's Ubuntu dan juga desktop Ubuntu (dan Fedora, dan AIX, dan NetBSD, dll.).
Kode inti dalam C dan C + GMP. next_prime dari MPU melihat jumlahnya terlalu besar dan meneruskannya ke bagian belakang GMP (atau kode Perl murni jika bagian belakang tidak diinstal). Itu menguatkan dan mengkonversi ke mpz, dan akan mengubah hasilnya kembali menjadi tipe objek input atau Math :: BigInt. next_prime sendiri tidak:
Kemungkinan ujian utama adalah:
Segala sesuatu sebelum ES BPSW hanyalah optimasi, yang tentu saja kita inginkan untuk next_prime. next_prime juga diimplementasikan dalam Perl menggunakan modul Math :: BigInt (pada intinya dengan Pari opsional dan ujung belakang GMP). Itu memang AES BPSW (seperti Pari) tetapi tidak dioptimalkan.
Saya telah memikirkan manfaat versi berbasis saringan parsial, menggunakan kisaran, misalnya, 2 manfaat. Saya hanya tidak yakin apakah ini akan benar-benar lebih baik, karena sebagian besar waktu kita akan melakukan penyaringan yang tidak perlu karena celahnya kecil, dan kadang-kadang untuk celah yang besar kita harus mengulanginya berkali-kali.
Perpustakaan mengimplementasikan ECPP (termasuk sertifikat) sehingga kami dapat menjalankan bukti pada hasilnya, tetapi 1200 digit benar-benar terlalu besar untuk kumpulan standar kecil dari polinomial yang disertakan (ada metode untuk mengunduh set yang lebih besar - bukti akan sedikit di bawah 15 menit yang sedikit lebih cepat dari APR-CL Pari tetapi sedikit lebih lambat dari mpz_aprcl WraithX). Satu kelemahan ECPP vs APR-CL adalah varians waktunya lebih banyak sehingga ada kemungkinan lebih dari 10 detik untuk beberapa angka sebelum waktu rata-rata tiba di sana. Dengan bukti saya pikir kami terbatas pada sesuatu dalam kisaran 400 digit kecuali kami mengizinkan perangkat lunak multi-threaded.
Saya memutuskan untuk mencoba dengan urutan yang sama yang digunakan oleh primo. Ia mencapai 1191 digit, karena di situlah kami mencapai celah 18.138. Saya juga menguji kode primo menggunakan my_math.py terbaru. Ia mencapai 630 digit dengan urutan 10 ^ dan 641 dengan urutannya. Sangat mengesankan untuk kode semua-Python yang ringkas tanpa banyak pretest.
sumber
Math::GMP
dengan cara yang tidak begitu boros dengan pembuatan / penghancuran referensi mpz.$x = new Math::GMP(0); $x += 3 for 1..1000000
. Saya akan memposting ke cpan ketika saya selesai; Anda akan menjadi salah satu yang pertama tahu;)