Anda memiliki n
koin yang masing-masing berbobot -1 atau 1. Masing-masing diberi label dari 0
hingga n-1
sehingga Anda dapat membedakan koin tersebut. Anda memiliki satu alat penimbang (ajaib) juga. Pada belokan pertama Anda dapat menaruh koin sebanyak yang Anda suka di alat penimbang yang dapat mengukur bobot negatif dan positif dan itu akan memberi tahu Anda berapa beratnya.
Namun, ada sesuatu yang sangat aneh dengan alat penimbang ini. Jika Anda meletakkan koin x_1, x_2, ..., x_j
pada perangkat pertama kali, maka pada saat berikutnya Anda harus meletakkan koin (x_1+1), (x_2+1) , ..., (x_j+1)
pada skala dengan pengecualian bahwa Anda tentu saja tidak dapat memakai koin yang bernomor lebih tinggi dari n-1
. Tidak hanya itu, untuk setiap penimbangan baru Anda bisa memilih jika Anda juga ingin menempatkan koin 0
pada skala.
Di bawah aturan ini, berapakah jumlah penimbangan terkecil yang akan selalu memberi tahu Anda dengan tepat koin mana yang berbobot 1 dan yang berbobot -1?
Jelas Anda hanya bisa meletakkan koin 0
pada perangkat di belokan pertama dan kemudian akan benar-benar n
menimbang untuk menyelesaikan masalah.
Bahasa dan perpustakaan
Anda dapat menggunakan bahasa atau pustaka yang Anda suka (yang tidak dirancang untuk tantangan ini). Namun, saya ingin dapat menguji kode Anda jika memungkinkan jadi jika Anda dapat memberikan instruksi yang jelas tentang cara menjalankannya di Ubuntu yang akan sangat dihargai.
Skor
Untuk yang diberikan n
skor Anda n
dibagi dengan jumlah penimbangan yang Anda butuhkan dalam kasus terburuk. Skor yang lebih tinggi karenanya lebih baik. Tidak ada input untuk teka-teki ini tetapi tujuan Anda adalah untuk menemukan n
yang Anda bisa mendapatkan skor tertinggi.
Jika ada seri, jawaban pertama menang. Dalam situasi yang sangat tidak mungkin di mana seseorang menemukan cara untuk mendapatkan skor tanpa batas, orang itu segera menang.
Tugas
Tugas Anda hanyalah menulis kode yang mendapat skor tertinggi. Kode Anda harus memilih dan cerdas serta mengoptimalkan jumlah penimbangan untuk itu n
.
Entri terkemuka
4/37/5 dalam Python oleh Sarge Borsch- 26/14 di Jawa oleh Peter Taylor
sumber
x_i
: Kita dapat memiliki misalnya penimbangan pertama (x_1, x_2, x_3) = (3, 2, 7), dan kemudian penimbangan kedua dapat berupa (4, 3, 8) atau ( 0, 4, 3, 8). Label koin tidak harus berurutan, dan indeksi
dalamx_i
tidak mengacu pada label koin.Jawaban:
C ++, Skor
23/1225/1327/1428/14 = 231/15Solusi Matrix properti X yang ditinjau kembali (atau Joy of X) langsung dapat digunakan sebagai solusi untuk masalah ini. Misalnya solusi 31 baris 15 kolom:
baris N menunjukkan koin yang Anda masukkan pada skala untuk pengukuran N. Apa pun hasil pembobotan yang Anda dapatkan, jelas ada beberapa set nilai koin yang memberikan bobot itu. Jika ada kombinasi lain juga (solusinya tidak unik) pertimbangkan perbedaannya. Anda harus mengganti satu set koin yang berbobot
1
dengan koin yang berbobot-1
. Ini memberikan satu set kolom yang sesuai dengan flip itu. Ada juga serangkaian koin-1
yang Anda ganti1
. Itu adalah kumpulan kolom lainnya. Karena pengukuran tidak berubah di antara dua solusi yang berarti jumlah kolom dari dua set harus sama. Tetapi solusi untuk properti Matrix X ditinjau kembali (atau Joy of X) persis matriks ini di mana set kolom seperti itu tidak ada, sehingga tidak ada duplikat dan setiap solusi unik.Setiap set pengukuran aktual dapat dijelaskan oleh beberapa
0/1
matriks. Tetapi bahkan jika beberapa kolom menetapkan penjumlahan ke vektor yang sama, bisa jadi tanda-tanda nilai solusi koin kandidat tidak persis sesuai dengan set tersebut. Jadi saya tidak tahu apakah matriks seperti di atas optimal. Tapi setidaknya mereka memberikan batas bawah. Jadi kemungkinan bahwa 31 koin dapat dilakukan dalam waktu kurang dari 15 pengukuran masih terbuka.Perhatikan bahwa ini hanya berlaku untuk strategi tidak tetap di mana keputusan Anda untuk meletakkan koin
0
pada timbangan tergantung pada hasil dari bobot sebelumnya. Kalau tidak, Anda akan memiliki solusi di mana tanda-tanda koin sesuai dengan set yang memiliki jumlah kolom yang sama.sumber
Python 2, skor = 1.0
Ini adalah skor yang mudah, kalau-kalau tidak ada yang menemukan skor yang lebih baik (ragu-ragu).
n
berat masing-masingn
.Saya mengimpor
antigravity
agar program dapat bekerja dengan bobot negatif.sumber
antigravity
pada dasarnya adalah larangan, bukan?Nilai = 26/14 ~ = 1.857
Simpan sebagai
LembikWeighingOptimisation.java
, kompilasi sebagaijavac LembikWeighingOptimisation.java
, jalankan sebagaijava LembikWeighingOptimisation
.Banyak terima kasih kepada Mitch Schwartz karena menunjukkan bug dalam versi pertama dari penolakan cepat.
Ini menggunakan beberapa teknik yang cukup mendasar yang saya tidak bisa membenarkan dengan ketat. Itu brute-force, tetapi hanya untuk memulai operasi penimbangan yang menggunakan paling banyak setengah dari koin: urutan yang menggunakan lebih dari setengah koin tidak secara langsung dapat ditransfer ke penimbangan komplementer (karena kita tidak tahu berat total), tetapi pada tingkat bergelombang tangan harus ada jumlah informasi yang sama. Hal ini juga beralih melalui penimbangan awal dalam urutan jumlah koin yang terlibat, atas dasar bahwa cara itu mencakup penimbangan yang tersebar (yang diharapkan memberikan informasi tentang ujung atas relatif awal) tanpa terlebih dahulu merangkak melalui sekelompok yang dimulai dengan subset padat di ujung bawah.
The
MaskRange
kelas perbaikan besar-besaran pada versi sebelumnya dalam hal penggunaan memori, dan menghapus GC dari menjadi hambatan.sumber
Python 3,
skor = 4/3 = 1.33 ... (N = 4)skor = 1.4 (N = 7)Pembaruan: menerapkan pencarian brute-force di set "static" solver, dan mendapat hasil baru
Saya pikir itu bisa lebih ditingkatkan dengan mencari pemecah dinamis, yang dapat menggunakan hasil pembobotan untuk keputusan lebih lanjut.
Berikut adalah kode Python yang mencari melalui semua pemecah statis untuk nilai kecil
n
(pemecah ini selalu menimbang set koin yang sama, maka nama "statis") dan menentukan jumlah kasus terburuk dari langkah-langkah hanya dengan memeriksa bahwa hasil pengukuran mereka hanya memungkinkan satu koin yang cocok. diatur dalam semua kasus. Juga, itu melacak skor terbaik yang ditemukan sejauh ini dan pemecah plum awal yang telah menunjukkan bahwa mereka pasti lebih buruk daripada yang ditemukan sebelumnya. Ini adalah optimasi yang penting, jika tidak saya tidak bisa menunggu hasil ini dengann
= 7. (Tapi itu jelas masih belum dioptimalkan dengan sangat baik)Jangan ragu untuk bertanya jika tidak jelas cara kerjanya ...
Hasil:
Baris ini
(StaticSolver({0,2}, {0,1,3}, {0,1,2,4}, {1,2,3,5}, {0,2,3,4,6}), 5), score = 7/5 = 1.4
mengungkap pemecah terbaik yang ditemukan. Angka-angka dalam{}
kawat gigi adalah indeks koin untuk diletakkan di alat pembobot pada setiap langkah.sumber