Kunci kombinasi N-digit biasa terdiri dari N disc yang berputar. Setiap disk memiliki angka 0-9 yang ditulis secara berurutan, dan Anda perlu mengubahnya ke kata sandi yang benar untuk membukanya. Tentunya, jika Anda tidak tahu kata sandinya, Anda harus mencoba paling banyak 10 N kali sebelum membukanya. Itu tidak menarik.
Jadi mari kita pertimbangkan varian kunci kombinasi, beri nama kunci pengungkap jarak.
Dalam setiap upaya yang gagal untuk membuka kunci pengungkapan jarak, itu akan merespon jumlah minimum gerakan untuk membuka kunci.
Satu gerakan didefinisikan sebagai rotasi oleh satu posisi, misalnya diperlukan 1 gerakan dari 890
ke 899
, dan 9 gerakan dari 137
ke 952
.
Tantangan
Mengingat kunci pengungkap jarak dengan kata sandi tidak dikenal, coba buka kunci dengan jumlah upaya minimal (bukan gerakan), sambil menjaga program agar tidak terlalu lama.
Aturan & Penilaian
- Anda harus menulis program lengkap yang input dari stdin dan output ke stdout. Program harus melakukan input / output sebagai berikut:
Start
Input an integer N (number of digits) from stdin
Do
Output a line containing decimal string of length N (your attempt) to stdout
Input an integer K (response of the lock) from stdin
While K not equal 0
End
Program Anda harus menangani hingga N = 200, dan harus berjalan kurang dari 5 detik pada input apa pun.
Nol terdepan dalam output tidak boleh diabaikan.
Ini adalah 5 testdata untuk setiap panjang, sehingga jumlah total testdata adalah 1000. Testdata dihasilkan secara acak.
Skor akhir akan menjadi (jumlah total tebakan di semua testdata) * ln (panjang kode dalam byte + 50). Skor terendah menang. (Dalam log alami)
Saya akan mencetak skor program untuk Anda. Jika Anda ingin tahu bagaimana saya akan menilai program Anda, atau Anda ingin membuat skor sendiri, lihat suntingan sebelumnya pada posting ini .
Tantangan ini akan berakhir pada 2017/12/07 14:00 UTC. Saya akan memposting solusi saya kemudian.
Contoh Menjalankan
Baris dimulai dengan >
mewakili input, dan lainnya mewakili output program.
Anda dapat memiliki kata sandi di pikiran Anda dan berinteraksi dengan program Anda untuk mengujinya.
> 3 # 3-digit lock. The hidden password is 746
000 # 1st guess (by program)
> 11 # response to the 1st guess
555 # 2nd guess
> 4 # ...
755
> 2
735
> 2
744
> 2
746 # finally the correct answer! The program attempts 6 times.
> 0 # this is not necessary
Program Sampel
EDIT: Mungkin format input / output di atas tidak jelas. Berikut ini contoh program dengan Python.
Python, 369 byte, jumlah upaya = 1005973, skor = 6073935
import sys
N = int(input()) # get the lock size
ans = ''
for i in range(N): # for each digit
lst = []
for j in range(10): # try all numbers
print('0' * i + str(j) + '0' * (N - i - 1)) # make a guess
result = int(input()) # receive the response
lst.append(result)
ans += str(lst.index(min(lst)))
print(ans) # output the final answer
Terima kasih kepada Jonah karena menyederhanakan tantangan.
sumber
162751*ln(388+50)=989887
.C # (.NET Core) , 617 byte, upaya total = 182255, skor = 1185166
Semoga C # dalam format ini berfungsi untuk Anda. Itu dalam bentuk program yang lengkap, jadi harus ada cara untuk dikompilasi ke executable. Beri tahu saya jika ada yang bisa saya lakukan untuk membuatnya lebih mudah. Bytes adalah bagian dari penilaian meskipun tag Golf Code dihapus sehingga kiriman resmi saya menghapus semua spasi kosong yang tidak dibutuhkan dan nama-nama berguna. Penjelasan saya di bawah ini akan menggunakan bagian-bagian dari kode yang tidak dikenali:
Penjelasan
Program ini hanya menggunakan metode pembantu tunggal:
Ini menulis tebakan ke stdout, kemudian membaca jarak dari stdin. Ini juga segera mengakhiri program jika tebakan adalah kombinasi yang tepat. Saya sering menyebutnya. Selanjutnya pengaturan awal:
Ini mendapatkan panjang kombinasi, lalu mulai menebak dengan semua 0s. Setelah itu, iterates melalui setiap digit dalam satu
for
lingkaran.Untuk setiap digit, tebakan 5, lalu putuskan pada langkah berikutnya berdasarkan bagaimana jarak berubah sejak tebakan sebelumnya (di mana angka itu 0).
Jika jarak bertambah 5, maka 0 benar untuk jarak itu. Sesuaikan angka itu kembali ke 0. Mengubah jarak yang direkam secara manual mencegah tebakan tambahan.
Jika jarak menurun 5, maka 5 adalah digit yang benar dan kami segera pindah ke digit berikutnya.
Setelah itu semuanya rumit. Menggunakan
5
dan0
untuk tebakan awal saya berarti bahwa kemungkinan perbedaan yang tersisa adalah3, 1, -1, -3
dengan 2 kemungkinan untuk masing-masing, yang membutuhkan 1 tebakan tambahan untuk membedakan. Masing-masing kasus ini mengambil bentuk yang serupaBeberapa angka berubah, tetapi pada dasarnya kami mencoba salah satu dari dua kemungkinan, dan memeriksa apakah perubahan itu yang benar untuk angka itu. Jika tidak, maka digit lainnya sudah benar sehingga kami mengatur digit itu lalu menyesuaikan perbedaannya secara manual.
Metode ini berarti kita harus mensyaratkan, paling banyak, 1 tebakan untuk 0s awal, 2 tebakan per digit, dan kemudian 1 tebakan akhir untuk memastikan digit terakhir tidak jatuh.
Mungkin buggy, itu berfungsi sejauh saya sudah memeriksa secara manual tapi itu bukan jaminan.Bug ditemukan dan tergencet berkat Colera Susumber
37
. Outputnya adalah:00, 50, 30, 75, 75
(ya, dua 75-an).<
dengan>
di setiapif
diswitch
tampaknya memperbaiki bug. Jika itu yang Anda inginkan, skor Anda adalah182255*ln(617+50)=1185166
.Python 2 dan 3: 175 byte, total upaya = 1005972, skor = 5448445
Program ini membutuhkan ceil (log (n)) * 10 upaya per kombinasi atau setiap digit membutuhkan 10 upaya (jadi,
333
dibutuhkan 30 upaya).Terima kasih banyak kepada Colera Su karena telah membantu saya dengan fungsionalitas input / output.
Versi Python dari Tantangan ( Dimodifikasi oleh OP ).
Saya menulis versi kode kunci di dalam Python. Anda dapat melanjutkan dan menggunakan jika Anda mencoba menyelesaikan ini dengan Python (seperti saya). Berikut ini berfungsi dalam Python 2 dan 3. Itu membuat lebih masuk akal hanya untuk menerapkan kunci sebagai kelas Anda dapat menguji dan saya memutuskan untuk membuat fungsi generator untuk menebak input.
sumber
LockIO
salah kelas. Saya telah mengirim permintaan edit. Kedua, saya pikir Anda salah membaca kriteria penilaian. Skor dihitung oleh testdata yang dihasilkan oleh generator, bukan contoh (Saya menjalankan program Anda, dan jumlah totalnya adalah 1005972). Log alami juga hilang. Ketiga, saya telah menetapkan bahwa Anda perlu menyediakan program lengkap, jadi Anda harus memasukkanLockIO
bagian dalam jumlah byte Anda juga. Selain itu, Anda perlu menampilkan hasil akhir, dan itu juga dihitung dalam skor.Lock
danmasterLock
hanya untuk kemudahan pengujian.LockIO
adalah apa yang sebenarnya perlu Anda kirim, karena menggunakan format I / O yang diperlukan.R ,
277 byte (skor = 1175356)258 byte, upaya total = 202999, skor = 1163205Cobalah online!
Versi stdin-stdout, seperti yang diminta oleh OP, tanpa pelat ketel. Terima kasih kepada Colera Su karena telah memperbaiki bug awal. Ini adalah versi yang sedikit lebih pendek daripada yang ada di komentar.
Di sini, di bawah pengajuan TIO untuk menjalankan serangkaian tes dalam TIO
R , 189 byte
Cobalah online!
Mari kita pertimbangkan vektor nol sebagai tebakan awal. Mari kita sebut V jarak antara perkiraan saat ini dan solusinya. Untuk setiap posisi Anda hanya perlu memeriksa perubahan dalam V ketika Anda mengganti 0 dengan 5 dan dengan 4. Bahkan, perbedaan antara mengubah 0 dengan 5 tercantum dalam vektor s1 saya. Perbedaan antara mengubah 0 dengan 4 tercantum dalam vektor s2 saya. Seperti yang Anda lihat, kedua vektor ini secara unik memetakan digit solusi.
Dengan demikian, total jumlah tes adalah
3 * L2 * L + 1, di mana L adalah panjang kode: pemeriksaan awal terhadap semua nol, lalu dua pemeriksaan untuk setiap digit, satu terhadap 5 dan satu terhadap 4.Peningkatan dari faktor 3 ke faktor 2 terinspirasi oleh pengajuan Kamil Drakari.
Sisa dari pengajuan TIO adalah boilerplate untuk R. Pengajuan TIO menunjukkan waktu berjalan dan jumlah total operasi untuk 1000 berjalan dengan L = 1 ... 200, 5 ulangan untuk setiap nilai L.
sumber
Error in scan(n = 1) : scan() expected 'a real', got 'S=rep(0,L)'
ketika mengeksekusi.scan(file=file("stdin"),n=1)
berhasil. Program ini (sama seperti milik Anda, hanya diperbaiki I / O) mendapatkan skor202999*ln(277+50)=1175356
.202999*ln(258+50) != 202999*ln(277+50)