Tugasnya adalah hanya untuk melihat seberapa cepat Anda dapat menghitung n memilih n / 2 (untuk genap n) daripada fungsi builtin dalam python. Tentu saja untuk besar n ini adalah angka yang agak besar sehingga daripada menampilkan seluruh nomor Anda harus menampilkan jumlah digit. Misalnya, untuk n = 100000
, jawabannya adalah 135702
. Untuk n=1000000
itu 1354815
.
Berikut adalah kode python:
from scipy.misc import comb
def sum_digits(n):
r = 0
while n:
r, n = r + n % 10, n / 10
return r
sum_digits(comb(n,n/2,exact=True))
Skor Anda adalah (highest n on your machine using your code)/(highest n on your machine using my code)
. Kode Anda harus berakhir dalam 60 detik atau kurang.
Program Anda harus memberikan hasil yang benar untuk semua genap n: 2 <= n <= (n tertinggi Anda)
Anda tidak dapat menggunakan kode atau pustaka bawaan yang menghitung koefisien atau nilai binomial yang dapat dengan cepat diubah menjadi koefisien binomial.
Anda dapat menggunakan bahasa pilihan Anda.
Jawaban terkemuka Jawaban terkemuka saat ini dengan 680,09 yang menakjubkan adalah dengan justhalf.
n
menghasilkan jutaan, sementara saya ragu fungsi Python akan menangani sesuatu yang lebih besar daripadan = 1e5
tanpa tersedak.Jawaban:
C ++ (GMP) - (287.000.000 / 422.000) = 680,09
Tanpa malu-malu menggabungkan Teorema Kummer dengan xnor dan GMP oleh qwr.
Masih bahkan tidak dekat dengan solusi Go, tidak yakin mengapa.Sunting: Terima kasih Keith Randall untuk pengingat bahwa multiplikasi lebih cepat jika angkanya sama. Saya menerapkan multiplikasi multi-level, mirip dengan konsep penggabungan memori pada manajemen memori. Dan hasilnya luar biasa. Apa yang digunakan untuk mengambil 51s, sekarang hanya membutuhkan 0,5s (yaitu, peningkatan 100 kali lipat !!)
Berlari untuk
n=287,000,000
Kode. Kompilasi dengan
-lgmp -lgmpxx -O3
sumber
n
, 18s menghitung koefisien binomial pusat, dan sisanya 37s dalam mengubah hasilnya menjadi string dan menjumlahkan digit.Go, 33,96 = (16300000/480000)
Bekerja dengan menghitung semua faktor utama dalam pembilang dan penyebut dan membatalkan faktor pencocokan. Lipat gandakan sisa makanan untuk mendapatkan hasilnya.
Lebih dari 80% waktu dihabiskan untuk mengonversi ke basis 10. Harus ada cara yang lebih baik untuk melakukan itu ...
sumber
Python 3 (8,8 = 2,2 juta / 0,25 juta)
Ini menggunakan Python, yang tidak dikenal untuk kecepatan, jadi Anda mungkin bisa melakukan porting ini dengan lebih baik ke bahasa lain.
Generator Primes diambil dari kontes StackOverflow ini .
Gagasan utama dari algoritma ini adalah menggunakan Teorema Kummer untuk mendapatkan faktorisasi utama dari binomial. Untuk setiap perdana, kita belajar kekuatan tertinggi yang membagi jawaban, dan melipatgandakan produk yang berjalan dengan kekuatan perdana itu. Dengan cara ini, kita hanya perlu melipatgandakan satu kali untuk setiap perdana dalam faktorisasi utama jawaban.
Output menunjukkan waktu kerusakan:
Anehnya, sebagian besar waktu dihabiskan untuk mengubah angka menjadi string untuk menjumlahkan digit-digitnya. Yang juga mengejutkan, mengonversi ke string jauh lebih cepat daripada mendapatkan digit dari pengulangan
%10
dan//10
, meskipun seluruh string harus disimpan dalam memori.Menghasilkan bilangan prima membutuhkan waktu yang dapat diabaikan (dan karenanya saya tidak merasa tidak adil menyalin kode yang ada). Penjumlahan digit cepat. Penggandaan aktual membutuhkan sepertiga waktu.
Mengingat penjumlahan digit tampaknya menjadi faktor pembatas, mungkin suatu algoritma untuk melipatgandakan angka dalam representasi desimal akan menghemat waktu secara total dengan memintas konversi biner / desimal.
sumber
Java (skor 22500/365000 = 0,062)
Saya tidak memiliki Python di mesin ini, jadi jika seseorang dapat mencetak skor ini saya akan berterima kasih. Jika tidak, itu harus menunggu.
Kemacetan adalah tambahan untuk menghitung bagian yang relevan dari segitiga Pascal (90% waktu berjalan), jadi menggunakan algoritma multiplikasi yang lebih baik tidak akan membantu.
Perhatikan bahwa yang dipanggil pertanyaan
n
adalah apa yang saya panggil2n
. Argumen baris perintah adalah apa yang disebut pertanyaann
.sumber
javac CodeGolf37270.java
) dan mengeksekusi dengan Java 1.8 (java CodeGolf37270 n
). Saya tidak yakin apakah ada opsi optimasi yang tidak saya sadari. Saya tidak dapat mencoba mengkompilasi dengan Java 1.8, karena itu tidak diinstal dengan paket Java saya ...GMP - 1500000/300000 = 5.0
Meskipun jawaban ini tidak akan bersaing dengan saringan, terkadang kode pendek masih bisa mendapatkan hasil.
sumber
Java, kelas integer besar tersuai: 32.9 (120000000/365000)
Kelas utama cukup mudah:
Ini bergantung pada kelas integer besar yang dioptimalkan untuk multiplikasi dan
toString()
, keduanya merupakan hambatan signifikan dalam implementasi denganjava.math.BigInteger
.Kemacetan besar adalah multiplikasi naif (60%), diikuti oleh multiplikasi lainnya (37%) dan pengayakan (3%). The
digsum()
panggilan tidak signifikan.Kinerja diukur dengan OpenJDK 7 (64 bit).
sumber
Python 2 (PyPy), 1.134.000 / 486.000 = 2,32
Hasil: 1,537,506
Fakta menyenangkan: Hambatan kode Anda adalah menambahkan angka, bukan menghitung koefisien binomial.
sumber
Java (2,020,000 / 491,000) = 4,11
diperbarui, sebelumnya 2.24
Jawa
BigInteger
bukan penghasil angka tercepat, tetapi lebih baik daripada tidak sama sekali.Rumus dasar untuk ini tampaknya
n! / ((n/2)!^2)
, tetapi tampaknya seperti sekelompok perkalian yang berlebihan.Anda bisa mendapatkan peningkatan yang signifikan dengan menghilangkan semua faktor utama yang ditemukan di pembilang dan penyebut. Untuk melakukan ini, saya pertama kali menjalankan ayakan perdana sederhana. Kemudian untuk setiap prime, saya menghitung berapa daya yang dibutuhkan untuk dinaikkan. Kenaikan setiap kali saya melihat faktor dalam pembilang, penurunan untuk penyebut.
Saya menangani keduanya secara terpisah (dan pertama), karena mudah untuk menghitung / menghilangkannya sebelum memfaktorkan.
Setelah selesai, Anda memiliki jumlah minimum perkalian yang diperlukan, yang bagus karena perkalian BigInt lambat .
Oh, dan jumlah output untuk n = 2020000 adalah
2735298
, untuk keperluan verifikasi.sumber