Pertimbangkan fungsi Remove(n, startIndex, count)
yang menghilangkan count
angka dari angka n
mulai dari angka di posisi startIndex
. Contoh:
Remove(1234, 1, 1) = 234
Remove(123456, 2, 3) = 156
Remove(1507, 1, 2) = 07 = 7
Remove(1234, 1, 4) = 0
Kami akan menyebut bilangan prima X rapuh jika setiap Remove
operasi yang memungkinkan membuatnya non-prima. Misalnya, 80651 adalah prime rapuh karena semua angka berikut ini tidak prima:
651, 51, 1, 0, 8651, 851, 81, 8, 8051, 801, 80, 8061, 806, 8065
Tujuan
Tulis program yang menemukan prime rapuh terbesar. Sunting: menghapus batas waktu karena ada cara yang relatif adil untuk menghindarinya.
Skornya adalah bilangan prima rapuh yang ditemukan oleh program Anda. Dalam hal seri, pengajuan sebelumnya menang.
Aturan
- Anda dapat menggunakan bahasa apa pun dan perpustakaan pihak ketiga mana pun.
- Anda menjalankan program di perangkat keras Anda sendiri.
- Anda dapat menggunakan tes primality probabilistik.
- Semuanya ada di base 10.
Entri terkemuka
- 6629 digit oleh Qualtagh (Jawa)
- 5048 digit oleh Emil (Python 2)
- 2268 digit oleh Jakube (Python 2)
Sunting: Saya telah menambahkan jawaban saya sendiri.
- 28164 digit oleh Suboptimus Prime, berdasarkan algoritma Qualtagh (C #)
code-challenge
primes
Suboptimus Prime
sumber
sumber
Jawaban:
Jawa -
314433226629 digit6 0{3314} 8969999
Solusi ini didasarkan pada jawaban FryAmTheEggman .
Bagaimana jika kita menggali lebih dalam?
Itu menjadi struktur pohon:
Mari kita panggil angka R komposit kanan jika R dan semua ujungnya komposit.
Kita akan mengulangi semua angka komposit yang benar dengan cara pertama: 1, 9, 01, 81, 91, 09, 49, 69, 99, 001, 801, 901 dll.
Angka-angka yang dimulai dengan nol tidak diperiksa untuk primality tetapi diperlukan untuk membangun angka lebih lanjut.
Kami akan mencari nomor target N dalam bentuk X00 ... 00R, di mana X adalah salah satu dari 4, 6, 8 atau 9 dan R adalah komposit yang benar. X tidak bisa menjadi prima. X tidak boleh 0. Dan X tidak bisa 1 karena jika R berakhir dengan 1 atau 9 maka N akan berisi 11 atau 19.
Jika XR berisi bilangan prima setelah operasi "hapus" maka XYR akan memuatnya juga untuk Y. Jadi, kita tidak boleh melintasi cabang mulai dari R.
Biarkan X menjadi konstanta, katakan 6.
Kodesemu:
Kita harus membatasi jumlah nol karena mungkin butuh waktu terlalu lama untuk menemukan bilangan prima dalam bentuk X + nol + R (atau selamanya jika semuanya adalah komposit).
Kode sebenarnya sangat bertele-tele dan dapat ditemukan di sini .
Pengujian primality untuk angka dalam rentang int panjang dilakukan oleh varian deterministik dari uji Miller. Untuk nomor BigInteger, divisi uji coba dilakukan terlebih dahulu dan kemudian uji BailliePSW. Ini probabilistik tetapi cukup pasti. Dan ini lebih cepat daripada tes Miller-Rabin (kita harus melakukan banyak iterasi untuk sejumlah besar di Miller-Rabin untuk mendapatkan akurasi yang cukup).
Sunting: upaya pertama tidak benar. Kita juga harus mengabaikan cabang yang dimulai dengan R jika X0 ... 0R adalah yang utama. Maka X0 ... 0YR tidak akan menjadi prime rapuh. Jadi cek tambahan ditambahkan. Solusi ini tampaknya benar.
Sunting 2: menambahkan pengoptimalan. Jika (X + R) dapat dibagi dengan 3 maka (X + nol + R) juga dapat dibagi dengan 3. Jadi (X + nol + R) tidak dapat menjadi prima dalam kasus ini dan R seperti itu dapat dilewati.
Sunting 3: tidak perlu melewati digit utama jika mereka tidak berada di posisi terakhir atau pertama. Jadi akhiran seperti 21 atau 51 ok. Tapi itu tidak banyak berubah.
Kesimpulan:
sumber
Python 2 -
1261221133717192268 digitAda sekitar len (n) ^ 2 angka yang dihasilkan dari Remove (n, startIndex, count). Saya mencoba meminimalkan angka-angka itu. Jika ada banyak digit di sebelah satu sama lain adalah sama, banyak dari angka yang dihasilkan ini dapat diabaikan, karena mereka muncul beberapa kali.
Jadi saya membawanya ke ekstrim, hanya 9 dan sedikit prima di tengah. Saya juga melihat prime rapuh di bawah 1 juta, dan melihat, bahwa ada prime rapuh. Mencari angka dengan angka 9 pada akhirnya bekerja dengan sangat baik, tidak yakin mengapa. 1 angka, 3, atau 4 9s pada akhirnya menghasilkan bilangan prima rapuh yang lebih kecil.
Ini menggunakan modul pyprimes . Saya tidak yakin, apakah itu bagus. Ini menggunakan tes miller_rabin, jadi itu probabilistik.
Program ini menemukan prime rapuh 126 digit ini dalam waktu sekitar 1 menit, dan selama sisa waktu pencarian itu tidak berhasil.
edit:
Baru saja melihat, bahwa Anda menghapus batas waktu. Saya akan menjalankan program ini pada malam hari, mungkin beberapa bilangan prima rapuh besar muncul.
edit 2:
Membuat program asli saya lebih cepat, jadi tetapi masih tidak ada solusi dengan lebih dari 126 digit. Jadi saya melompat di kereta dan mencari x 9s + 1 digit + y 9s. Keuntungannya, Anda harus memeriksa nomor O (n) untuk primality, jika Anda memperbaikinya y. Ia menemukan 1221 agak cepat.
edit 3:
Untuk angka 2268 angka saya menggunakan program yang sama, hanya membagi pekerjaan pada beberapa core.
sumber
Python 2.7 - 429623069
99993799Tidak ada optimasi apa pun, sejauh ini. Hanya menggunakan beberapa pengamatan sepele tentang bilangan prima rapuh (terima kasih kepada Rainbolt dalam obrolan):
Hanya berusaha membuat bola bergulir :)
Secara teknis ini berjalan sedikit lebih dari 15 menit, tetapi hanya memeriksa satu nomor dalam waktu tambahan.
is_prime
diambil dari sini (isaacg menggunakannya di sini ) dan probabilistik.Hanya sebuah catatan, ketika saya memulai ini dengan
n=429623069
saya bangun482704669
. Digit tambahan tampaknya benar-benar mematikan strategi ini ...sumber
Python 2,
828 digit5048 digitSeperti @Jakube tunjukkan, perdana pertama yang saya kirimkan sebenarnya tidak rapuh karena bug dalam kode saya. Memperbaiki bug itu mudah tetapi itu juga membuat algoritma lebih lambat secara signifikan.
Saya membatasi diri pada subset yang mudah dicari dari bilangan prima yang rapuh, yaitu yang hanya terdiri dari angka 9 dan tepat satu digit 7.
Saya menggunakan
is_prime
fungsi yang sama (dari sini ) sebagai @FryAmTheEggman.Edit:
Saya membuat dua perubahan untuk membuat algoritme lebih cepat:
Saya mencoba untuk melewatkan sebanyak mungkin pemeriksaan primality dan hanya kembali ketika prime prime yang rapuh ditemukan untuk memastikan itu benar-benar rapuh. Ada sejumlah kecil duplikat cek, jadi saya dengan kasar memoise fungsi pemeriksaan utama.
Untuk jumlah formulir
b*'9' + '7' + c*'9'
saya membatasi ukuranb
. Semakin rendah batas, semakin sedikit angka yang harus diperiksa, tetapi peluang meningkat untuk tidak menemukan prime rapuh besar sama sekali. Saya agak suka memilih 222 sebagai batas.Dengan beberapa ribu digit, cek perdana tunggal sudah dapat mengambil program saya beberapa detik. Jadi, saya mungkin tidak bisa melakukan yang lebih baik dengan pendekatan ini.
Silakan periksa kebenaran kiriman saya. Karena primality probabilistic memeriksa nomor saya secara teoritis tidak bisa menjadi prima, tetapi jika ya, itu harus rapuh. Atau saya telah melakukan sesuatu yang salah. :-)
sumber
C #,
1003928164 digitSunting: Saya membuat program lain berdasarkan algoritma Qualtagh dengan beberapa modifikasi kecil:
Jawaban lama:
Berikut adalah beberapa pola penting untuk bilangan prima rapuh:
di mana X bisa 1, 2, 4, 5, 7 atau 8.
Untuk angka seperti itu kita hanya perlu mempertimbangkan (panjang - 1) mungkin
Remove
operasi yang .Remove
Operasi lain menghasilkan duplikat atau angka gabungan. Saya mencoba mencari semua angka dengan 800 digit dan memperhatikan bahwa 4 pola muncul lebih sering daripada yang lain: 8007001, 8004001, 9997999, dan 6004009. Karena Emil dan Jakube menggunakan pola 999X999, saya memutuskan untuk menggunakan 8004001 saja. untuk menambah variasi.Saya telah menambahkan optimasi berikut ke algoritme:
sumber
Haskell -
12201277 digit ditetapkan untuk benar-benar nyataLebih baik - 1277 digit
Kode haskell
sumber