Hanya karena ketertarikan saya mencoba memecahkan masalah dari kategori "Baru-baru ini" dari Project Euler ( urutan Digit Sum ). Tetapi saya tidak dapat memikirkan cara untuk menyelesaikan masalah secara efisien. Masalahnya adalah sebagai berikut (dalam urutan pertanyaan asli memiliki dua yang di awal, tetapi tidak mengubah urutan):
Urutan Digit Sum adalah 1,2,4,8,16,23,28,38,49 .... di mana istilah adalah jumlah digit sebelum itu dalam urutan. Temukan istilah urutan. 10 15 t h
Solusi naif tidak dapat diimplementasikan karena membutuhkan banyak waktu. Saya mencoba untuk mengurangi masalah untuk kasus matriks eksponensial (yang akan memakan waktu jumlah waktu) tetapi tidak dapat datang dengan perulangan seperti itu pas kriteria linier sebagai perulangan untuk urutan ini adalah cukup aneh. Dapat dilihat bahwa urutannya diatur oleh perulangan:
di mana adalah istilah dari urutan dan adalah fungsi yang ketika diberi nomor alami sebagai input mengembalikan jumlah digit nomor (mis. ). Pendekatan kedua saya adalah mencoba menemukan beberapa pola dalam urutan. Dapat dilihat bahwa beberapa istilah pertama dari urutan dapat ditulis sebagai
a_1 = 1
a_2 = 1 + d( 1 )
a_3 = 1 + d( 1 ) + d( 1 + d( 1 ) )
a_4 = 1 + d( 1 ) + d( 1 + d( 1 ) ) + d( 1 + d( 1 ) + d( 1 + d( 1 ) ) )
a_5 = 1 + d( 1 ) + d( 1 + d( 1 ) ) + d( 1 + d( 1 ) + d( 1 + d( 1 ) ) ) + d( 1 + d(
1 ) + d( 1 + d( 1 ) ) + d( 1 + d( 1 ) + d( 1 + d( 1 ) ) ) )
Dari pola di atas, istilah urutan dapat dihasilkan dengan metode berikut:
- Tulis dengan simbol tambahan di antara mereka.
- Meninggalkan pertama , lalu menerapkan fungsi pada istilah berikutnya lalu pada istilah berikutnya, lalu pada istilah berikutnya dan seterusnya.
- Kemudian menerapkan metode di atas secara rekursif pada argumen masing-masing fungsi diterapkan.
misalnya jika n = 3 kami melakukan manipulasi berikut:
1 + 1 + 1 + 1 + 1 + 1 + 1 + 1
1 + d( 1 ) + d( 1 + 1 ) + d( 1 + 1 + 1 + 1 )
1 + d( 1 ) + d( 1 + d(1) ) + d( 1 + d( 1 ) + d( 1 +d( 1 ) ) )
Dengan pemrograman dinamis saya dapat menghasilkan istilah menggunakan metode di atas dalam waktu , yang lagi-lagi tidak lebih baik daripada solusi naif. O ( l o g ( 2 10 15 ) )
EDIT 1
Hal lain yang dapat diamati adalah bahwa . Misalnya . Tetapi saya tidak dapat menggunakan poin ini. Saya kembali mencoba menemukan hubungan perulangan linear (untuk matriks eksponensial), tetapi saya tidak dapat menemukannya.d ( a 6 ) = d ( 23 ) = d ( 32 ) = 5
EDIT 2
Berikut ini adalah grafik ketika urutan diplot untuk rentang yang lebih kecil ( istilah urutan pertama diplot).
PS: Saya tahu tidak disarankan untuk meminta solusi dari Project Euler. Tapi saya hanya ingin arah atau petunjuk baru, karena saya telah bergerak berputar-putar selama beberapa hari terakhir. Jika itu juga tidak dapat diterima, saya dapat menghapus pertanyaan jika disarankan.
sumber
You are given a106 = 31054319.
dalam masalah Euler asli adalah petunjuk.Jawaban:
Urutan Anda dijelaskan dalam oeis.org/A004207 sebagai jumlah digit. Ada beberapa poin bagus seperti urutan mod 9 memiliki pola berulang , ia berbagi akar digital dengan oeis.org/A065075 dan oeis.org/A001370 . Jika sifat-sifat itu berguna adalah masalah terbuka (karena tidak ada persamaan bentuk tertutup untuk nomor ). n - t h(1,2,4,8,7,5)∞ n−th
Ada beberapa properti dari urutan ini yang perlu disebutkan:n−th
Ketika Anda menghitung angka , Anda hanya perlu menyimpan penghitung (untuk mengetahui angka itu) dan nomor itu sendiri. Untuk me-restart tidak ada lagi yang diperlukan, karena angka berikutnya adalah angka saat ini + jumlah digitnya.
Mengambil beberapa langkah untuk memastikan kecepatan pada awalnya itu baik untuk memasukkan angka ke dalam array, menghindari perhitungan mod dan div naif, yang mahal. Ini memberikan percepatan dengan konstan, tetapi melihat waktu itu penting.
Dari titik awal Anda dapat menghitung yang berikutnya, dan berikutnya, dan berfungsi sampai beberapa titik, titik ini adalah jumlah digit yang berubah.
Yang lebih penting, pola berubah dengan meningkatnya jumlah.
Jumlah digit kecil dibandingkan dengan angka itu sendiri, sehingga hanya bagian dari angka yang akan berubah pada sebagian besar operasi.
Jadi apa yang bisa kita cache?
Kita tahu bahwa dengan dua angka dengan jumlah digit yang sama penambahan untuk mendapatkan nomor berikutnya akan sama. Bagaimana dengan yang berikutnya?
sasha
Peringatan spoiler, di bawah ini adalah pola cache yang cukup eksplisit
Itu tergantung pada kondisi tambahan, seperti angka yang tidak berubah dalam menjalankan , saya akan menyebutnya bergeser , jumlah awal sebagai awal .
Mengambil beberapa langkah sewenang - wenang , seperti , dan mulai dari hingga kita dapat men-cache setiap pola dari titik awal hingga , menghitung jumlah elemen (untuk mengetahui cara menangani penghitung, yang diperlukan untuk memberikan angka ), dan hafalkan. 0 9 100 n - t h100 0 9 100 n−th
Baik. Sampai sekarang setiap permulaan dibahas, apa perubahan di atas ? Sayangnya, pola ini berhenti bekerja, karena jika Anda mencoba dari membuat mulai sama dengan , angka berikutnya dihitung dengan sempurna, tetapi yang kedua rusak. 100 1100
100 1
Di sini kita harus membahas shift yang diatur ke dan mulai diatur ke . Ini juga berarti menghitung tabel untuk shift yang berbeda . 01 0
Apakah kita benar-benar perlu menghitung semuanya ? Tidak juga, tidak.1,2,4,8
Bagian dari tabel hanyalah satu lagi item awal.
Misalnya mulai dari memberi urutan yang sama bergeser. Jadi apakah kita perlu menghitung cache yang lebih lama? Tidak, kami menghitungnya sampai dengan pergeseran perubahan untuk menjemput lain run , sehingga akan menghemat banyak memori.
Sekarang ketika tabel dicakup, kita mulai dari pengaturan awal, memilih jumlah dari tabel, menambah penghitung dan melihat bahwa: dari kita mencapai , memperbarui variabel dan melompat ke , mengulangi langkah-langkah -> -> -> -> -> -> -> . Baik. Apa sekarang? 101 218 305 406 517 607 719 805 904 10031 101 218 305 406 517 607 719 805 904 1003
Kami dapat melanjutkan sampai pergeseran lebih tinggi dari yang dihitung.100,1000,10000,100000,1000000...
100
Lebih jauh kita bisa membangun lebih banyak berjalan dengan cepat, menghitung ulang berlari lebih besar, atau mengamati pola lain (seperti kita dapat secara parsial menggunakan kembali tabel yang sudah dihitung).
Lihatlah berbeda pergeseran seperti mereka semua memberikan yang sama run menjadi lingkungan yang sama untuk jumlah digit, maka kita dapat menggunakan tabel yang sama. Membuat tabel yang lebih besar dari elemen mempercepat proses lebih lanjut, membuat lompatan yang lebih besar sekaligus.100
sumber
Karena Anda meminta "arah atau petunjuk baru" dan saya tidak tahu jawabannya, saya akan meninggalkan ini di sini, saya harap ini membantu. beberapa ide:
Masuk akal akan ada pola mod 9, karena
Yang bisa Anda buktikan dengan induksi.
Ini berarti bahwa semua angka kongruen dengan jumlah digit mereka mod 9.
Selanjutnya,an=d(an)mod9⟹
Jika kita terus memperluas pengulangan ini kita dapatkan
Yang menjelaskan pola mod 9.
Itu juga membuat kita . Setiap iterasi kita mendapatkan celah yang dapat dibagi 9. Berapa lebar celah itu?an=9k+2n
Berikut ini beberapa kode kurang umum:
Plot (untuk 100 pertama) terlihat eksponensial, tapi saya pikir itu tidak sempurna.
Inilah output dari
Hal terakhir yang saya miliki adalah tampaknya jika Anda menjumlahkan angka-angka dari suatu angka, dan kemudian menjumlahkan angka-angka dari angka yang dihasilkan, dan mengulanginya, Anda akhirnya mendapatkan angka itu mod 9.
Masuk akal mengingat fakta di atas tentang kekuatan 10 mod 9.
Ini memberikan urutan angka yang menarik.
Sunting: Rupanya ini disebut "root digital".
sumber