Diberikan input bilangan bulat positif, hasilkan jumlah langkah yang diperlukan untuk menemukan input melalui pencarian biner mulai dari 1.
Kami mensimulasikan pencarian biner untuk integer yang diberikan sebagai input, di mana pencari yang disimulasikan berulang kali dapat menebak integer dan diberi tahu apakah itu terlalu tinggi, terlalu rendah, atau benar. Strategi untuk menemukan integer adalah sebagai berikut:
Biarkan n menjadi bilangan bulat yang diberikan sebagai input yang kami coba temukan.
Mulailah dengan tebakan 1. (Untuk setiap tebakan, tambahkan jumlah langkah (terlepas dari apakah itu benar atau tidak), dan segera berhenti dan hasilkan jumlah langkah jika tebakan itu benar.)
Gandakan tebakan berulang kali hingga tebakan lebih besar dari n (angka target). (Atau jika itu benar, tapi itu sudah dicakup oleh aturan tebakan-benar kami yang disebutkan di atas.)
Sekarang, atur batas atas kekuatan pertama 2 yang lebih besar dari n (yaitu angka yang baru saja ditebak), dan atur batas bawah kekuatan 2 langsung di bawahnya.
Tebakan berulang kali rata-rata (dibulatkan ke bawah) dari batas atas dan batas bawah. Jika terlalu tinggi, atur sebagai batas atas. Jika terlalu rendah, atur sebagai batas bawah. Prosedur ini dijamin pada akhirnya menghasilkan tebakan yang benar.
Berikut ini contoh, untuk input n = 21:
1 -> 2 -> 4 -> 8 -> 16 -> 32 -> 24 -> 20 -> 22 -> 21
\__________________________/
repeated doubling \________________________/
repeated averaging
Karena ini adalah kode-golf , kode terpendek dalam byte akan menang.
Berikut ini semua keluaran dari n = 1 hingga n = 100:
1
2
4
3
6
5
6
4
8
7
8
6
8
7
8
5
10
9
10
8
10
9
10
7
10
9
10
8
10
9
10
6
12
11
12
10
12
11
12
9
12
11
12
10
12
11
12
8
12
11
12
10
12
11
12
9
12
11
12
10
12
11
12
7
14
13
14
12
14
13
14
11
14
13
14
12
14
13
14
10
14
13
14
12
14
13
14
11
14
13
14
12
14
13
14
9
14
13
14
12
Dan berikut ini beberapa kasus uji yang lebih besar:
1234 -> 21
1337 -> 22
3808 -> 19
12345 -> 28
32768 -> 16
32769 -> 32
50000 -> 28
Jelly,
1815109 byteCobalah online! atau memverifikasi kasus uji kecil dan kasus uji besar .
Latar Belakang
Biarkan n menjadi bilangan bulat positif dan m kekuatan terkecil 2 yang lebih besar atau sama dengan atau sama dengan n .
The menggandakan fase mengambil satu langkah untuk setiap digit dalam representasi biner dari m .
Ambil representasi biner dari n , hapus digit pertama, paling signifikan (selalu 1 ) dan semua nol trailing. Fase rata - rata mengambil satu langkah untuk setiap digit yang tersisa.
Untuk menghindari penghitungan m , kami mengamati bahwa, jika n <m , jumlah digit biner dari n persis satu kurang dari jumlah digit biner dari m .
Jika kita mengganti digit biner pertama dari n dengan 0 , membalikkan hasilnya, menambahkan digit biner asli dan menghapus semua nol terkemuka, kemudian terjadi:
Jika n adalah kekuatan 2 , semua digit dari bagian pertama (yang dimodifikasi) dihilangkan, hanya menyisakan digit dari representasi biner asli dari n = m .
Jika n adalah bukan kekuatan 2 , angka di babak pertama yang sesuai dengan digit yang paling signifikan tidak tidak bisa dihapus, kompensasi untuk kenyataan bahwa n memiliki digit biner kurang dari m .
Bagaimana itu bekerja
sumber
’B;Bt0L
(7 byte) berfungsi di versi terbaru Jelly, menggunakan pendekatan yang sama seperti pada jawaban Julia saya .ES6, 38 byte
Seperti disinggung oleh jawaban lain, Anda dapat menghitung jumlah langkah dari posisi bit pertama dan terakhir.
Jumlah langkah dalam fase penggandaan adalah
n=33-Math.clz32(x-1)
. Kami ingin 2ⁿ ≥ x tetapin=33-Math.clz32(x)
memberi kami 2ⁿ> x sehingga kami mengurangi 1 dari x untuk mengkompensasi.Jumlah langkah dalam fase rata-rata lebih mudah, sederhana saja
n=Math.clz32(x&-x)-Math.clz32(x)
.x&-x
adalah ungkapan praktis yang mengevaluasi ke bit terendahx
(sebagai kekuatan 2).sumber
x&-x
kerjanya? Saya akan berpikir bahwa itu akan mengevaluasi nilai absolut x.Pyth,
1513 byteSaya telah menemukan bahwa angka yang akan dihitung adalah
1 + 2*ceil(log_2(x)) - [number of 2s in x's prime factorization, minus 1 if x is a power of 2 greater than 1].
Coba di sini .
sumber
Julia,
3735 byteTerima kasih kepada @AlexA. untuk menghemat 2 byte!
Ini mengikuti pengamatan dari jawaban Jelly saya , tetapi berurusan secara berbeda dengan kasus tepi.
Jika n> 1 , representasi biner dari n - 1 memiliki satu digit lebih kecil dari kekuatan selanjutnya dari 2 , yang dikompensasi dengan tidak menghilangkan digit pertama dari representasi biner dari n .
Dengan menghapus semua nol dari kedua sisi , kami juga menangani casing tepi 1 .
sumber
Haskell, 82 byte
Ini adalah implementasi yang cukup mudah di Haskell:
Kurang golf:
sumber