Catatan : Sesuai konsensus di Meta , pertanyaan penulisan tantangan ada di topik di sini.
Mengingat "hal yang harus dihindari ketika menulis tantangan" , saya mulai berpikir tentang tantangan yang melibatkan generasi acak dari jenis objek tertentu.
Terkadang saya ingin memposting tantangan kode-golf yang melibatkan pembuatan foo secara acak, di mana
- sangat mudah untuk memeriksa apakah sesuatu yang diberikan adalah foo, dan
- sedikit lebih sulit untuk secara cepat menghasilkan foo acak "berkualitas baik".
Sebagai contoh, foo mungkin berupa matriks biner di mana tidak ada segmen dengan 4 bit yang sama ke segala arah. Sangat mudah untuk memeriksa apakah matriks biner yang diberikan adalah foo, tetapi menghasilkan foo acak dengan distribusi yang tersebar nampaknya membutuhkan algoritma penelusuran ulang atau sesuatu yang serupa.
Ngomong-ngomong, sekarang saya harus menentukan secara objektif apa yang memenuhi syarat sebagai foo acak, dan saya ingin itu "tidak dapat diprediksi" dalam arti intuitif bahwa ketika saya menjalankan program beberapa kali, hasilnya selalu terlihat berbeda. Pendekatan yang paling restriktif adalah mensyaratkan bahwa outputnya acak acak: semua foo yang valid memiliki kemungkinan yang sama untuk dihasilkan. Ini biasanya terlalu membatasi, karena saya tidak tahu bagaimana cara menyimpannya untuk menghasilkan semua foo yang valid, menghapus duplikat dan memilih satu, yang membosankan dan lambat.
Ide saya berikutnya adalah mengharuskan semua foos yang valid memiliki kemungkinan positif untuk dihasilkan. Namun, ini berarti bahwa pendekatan berikut ini valid: menghasilkan hal seperti foo acak (dalam contoh kami, matriks biner acak), jika itu foo lalu kembalikan, jika tidak kembalikan foo kode keras (katakanlah, matriks identitas ). Ini juga agak membosankan, karena itu pada dasarnya hanya sebuah pengenalan foo ditempelkan ke generator matriks acak.
Mungkinkah ada definisi umum yang bagus untuk foo acak yang tidak terduga?
TL; DR
Apakah ada cara yang baik untuk menentukan objek yang dihasilkan secara acak yang "tidak dapat diprediksi" yang tidak memperbaiki distribusi tetapi tidak mendukung pengkodean keras?
Jawaban:
Kembalikan seribu foo yang berbeda
Ini membuatnya tidak mungkin untuk mengembalikan nilai-nilai hardcoded dan memiliki golf yang layak. Namun, generator foo yang sah memiliki peluang kecil untuk menghasilkan duplikat foo kecuali jika benar-benar memeriksa mereka. Untuk menghilangkan beban pemeriksaan, tingkat kegagalan yang diuji secara empiris, katakanlah 10%, dapat ditetapkan sebagai dapat diterima.
Waspadai paradoks ulang tahun , bahwa kemungkinan duplikat mungkin lebih tinggi dari yang Anda pikirkan. Jika hanya ada satu juta foo yang mungkin, seribu foo acak akan memiliki probabilitas sekitar 0,6 bahwa ada duplikat di sana di suatu tempat, dan itu mengasumsikan bahwa generasi foo benar-benar seragam. Jika ini bisa menjadi masalah, perlu katakan 900 foo unik untuk setiap 1000 yang dihasilkan, yang jauh lebih murah untuk generator foo asli tetapi masih tidak praktis untuk hardcoding.
Ini juga memungkinkan Anda untuk berulang kali menghasilkan hal-hal seperti foo dan memeriksa fooness sampai Anda mendapatkan foos. Saya pikir ini adalah solusi yang valid sendiri, tetapi jika Anda tidak menyukainya:
Lakukan dengan cepat
Peluang untuk hal-hal seperti foo yang benar-benar acak menjadi foo mungkin cukup rendah, sehingga menentukan batas waktu kemungkinan akan memaksa upaya asli pada generasi foo.
Untuk mengakomodasi perbedaan kecepatan antara bahasa yang berbeda, Anda mungkin ingin memiliki batas waktu yang berbeda tergantung pada bahasa seperti Hackerrank: https://www.hackerrank.com/environment . Namun, jika Anda menentukan foo yang cukup besar, kemungkinan foo-like foo-like foo mungkin sangat rendah, sehingga aturan "sebelum kematian panas Semesta" mungkin cukup.
sumber
Saya tidak mengklaim memiliki solusi akhir untuk masalah ini (atau bahwa daftar ini lengkap), tetapi saya ingin menguraikan beberapa pendekatan yang mungkin muncul dalam pikiran dan mengapa mereka mau atau tidak berhasil. Saya juga tidak akan membahas masalah tangensial seperti apakah menggunakan stempel waktu saat ini sebagai sumber keacakan cukup "tidak dapat diprediksi" dan bagaimana menegakkan properti tertentu dari distribusi probabilitas - saya hanya akan fokus pada menghindari solusi yang menggunakan hardcoding.
Bukan solusi: melarang hard-coding secara eksplisit
Ini ide yang buruk. Ini adalah persyaratan yang tidak dapat diobservasi (yang berarti Anda tidak dapat menentukan apakah itu puas hanya dengan menjalankan program), yang sangat tidak disarankan di PPCG dan mungkin sama sekali tidak mungkin jika menjalankan program pada platform lain, di mana pengiriman diverifikasi dalam suatu cara otomatis. Masalah dengan persyaratan seperti ini adalah Anda harus mulai dengan menemukan definisi objektif untuk "hard-coding". Secara umum, jika Anda mencoba ini, Anda hanya akan memperburuk keadaan.
Membuat hard-coding tidak mungkin
Jika Anda tidak dapat sepenuhnya melarangnya, tetapi Anda tidak ingin orang menggunakannya, maka Anda dapat mencoba merancang tantangan sedemikian rupa sehingga hard-coding sama sekali bukan pendekatan kompetitif. Ini dimungkinkan jika objek yang harus dihasilkan cukup besar dan tidak dapat dimampatkan sehingga memasukkan satu contoh ke dalam kode akan membutuhkan lebih banyak byte daripada menulis algoritma yang menghasilkan solusi yang valid secara acak. Dalam contoh spesifik Anda, tentu saja bukan itu masalahnya, karena matriks identitas valid dan umumnya mudah dibuat, tetapi untuk masalah lain, mungkin bukan itu masalahnya. Jika objek target cukup tidak beraturan, cukup minta mereka berukuran besar, yang mungkin tidak akan memengaruhi jumlah byte dari algoritma aktual tetapi akan meledakkan bagian hard-coded.
Parameterkan output
Seringkali, masalah ini datang dengan satu atau lebih parameter alami, seperti ukuran matriks pada contoh Anda. Jika demikian, menjadikan parameter itu input yang cukup untuk membuat hard-coding tidak mungkin atau setidaknya tidak praktis. Dalam beberapa kasus, mungkin sulit untuk membuat kode satu solusi spesifik untuk nilai parameter tertentu yang telah ditemukan secara manual atau melalui pencarian ekstensif, tetapi mungkin tidak ada formulir tertutup sederhana untuk instance dari solusi ini secara umum, jadi tidak mungkin untuk menghasilkan nilai default untuk input sewenang-wenang dengan mudah. Sekali lagi, ini bukan kasus untuk contoh yang Anda sebutkan, karena matriks identitas bekerja pada ukuran berapa pun, tetapi solusi optimal untuk masalah terkait inibiasanya sangat tidak teratur, jadi tidak mungkin untuk memiliki nilai default tanpa tetap mencari nilai yang valid. Anda dapat menggabungkan ini dengan batas waktu untuk menghindari pencarian brute force untuk nilai default.
Masukan beberapa pembatasan distribusi probabilitas
Jika Anda bersedia menyerahkan distribusi probabilitas yang sepenuhnya tidak dibatasi, Anda dapat menempatkan beberapa kendala padanya, yang masih memberi banyak kebebasan kepada penjawab dalam memilih distribusi mereka tetapi yang membuat hard-coding menjadi sulit atau tidak mungkin:
Masalah utama dengan pendekatan ini adalah bahwa mereka jauh lebih sulit untuk dipikirkan, membuktikan kebenaran jawaban itu sulit, dan secara eksperimental memverifikasi kebenaran bisa mustahil untuk ruang output yang besar. Namun, mereka memberikan persyaratan yang pada dasarnya dapat diamati untuk program yang dapat membuat hardcoding tidak mungkin.
Pendekatan-pendekatan ini mungkin juga memerlukan batas waktu, karena salah satu cara untuk meningkatkan probabilitas nilai-nilai non-standar adalah dengan mencoba menemukan foo acak beberapa kali sebelum jatuh kembali ke nilai default.
sumber