Jumlah langkah untuk pencarian biner

12

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 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
Gagang pintu
sumber

Jawaban:

10

Japt, 13 12 byte

Ya ampun, aku mengalahkan Jelly dan Pyth untuk sementara waktu: D

¢a1 ªJ +1+¢l

Uji secara online!

Inilah strategi yang saya gunakan: misalkan x menjadi integer input, dan biarkan b menjadi representasi biner x . Output yang benar adalah 1 + panjang b + indeks terakhir dari 1 di b , minus 1 jika indeks ini adalah 0.

Produksi ETH
sumber
2
Sudah kubilang Dennis akan menang.
lirtosiast
7

Jelly, 18 15 10 9 byte

B>WU;BḄBL

Cobalah 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

B>WU;BḄBL  Main link. Input: n

B          Compute the binary representation of n.
 >W        Compare it with [n].
           n is positive, so it is not less than the first binary digit and the
           comparison yields zero. When comparing lists of different length, the
           elements in the longer list that do not have a pair remain untouched.
           Therefore, this will just zero out the first binary digit.
   U       Reverse the modified binary representation.
    ;B     Concatenate it with the unmodified binary representation of n.
      ḄB   Convert from binary to integer, and back to binary.
           This removes leading zeroes.
        L  Get the length of the resulting array.
Dennis
sumber
’B;Bt0L(7 byte) berfungsi di versi terbaru Jelly, menggunakan pendekatan yang sama seperti pada jawaban Julia saya .
Dennis
4

ES6, 38 byte

x=>33-(g=Math.clz32)(x-1)+g(x&-x)-g(x)

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 tetapi n=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&-xadalah ungkapan praktis yang mengevaluasi ke bit terendah x(sebagai kekuatan 2).

Neil
sumber
Bagaimana cara x&-xkerjanya? Saya akan berpikir bahwa itu akan mengevaluasi nilai absolut x.
ETHproduksi
2
Saya menemukan penjelasan yang bagus di halaman ini (lihat bit-hack # 7).
ETHproduksi
2

Pyth, 15 13 byte

h-y.ElQ/PPyQ2

Saya 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 .

lirtosiast
sumber
2

Julia, 37 35 byte

n->endof(strip(bin(n-1)bin(n),'0'))

Terima 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 .

Dennis
sumber
0

Haskell, 82 byte

Ini adalah implementasi yang cukup mudah di Haskell:

f x=[j|j<-[1..],let g i|i<2=1|x>g(i-1)=2*g(i-1)|1<2=div(g(i-1)+g(i-2))2,g j==x]!!0

Kurang golf:

f x = head [ stepNum | stepNum <- [1..], step stepNum == x]
  where
    prevStep i = step (i-1)
    step i | i == 1         = 1
           | x > prevStep i = 2 * prevStep i
           | otherwise      = div (prevStep i + step (i-2)) 2
Michael Klein
sumber