Số bước cho tìm kiếm nhị phân


12

Đưa ra một đầu vào của một số nguyên dương, xuất ra số bước cần thiết để tìm đầu vào thông qua tìm kiếm nhị phân bắt đầu từ 1.

Chúng tôi đang mô phỏng tìm kiếm nhị phân cho số nguyên được đưa ra làm đầu vào, trong đó người tìm kiếm mô phỏng có thể liên tục đoán một số nguyên và được cho biết liệu nó có quá cao, quá thấp hay chính xác hay không. Chiến lược tìm số nguyên như sau:

  • Đặt n là số nguyên được cho là đầu vào mà chúng ta đang cố gắng tìm.

  • Bắt đầu với số lần đoán là 1. (Đối với mỗi lần đoán, hãy tăng số bước (bất kể nó có đúng hay không), và ngay lập tức dừng và xuất tổng số bước nếu đoán đúng.)

  • Nhân đôi số lần đoán cho đến khi số lần đoán lớn hơn n (số mục tiêu). (Hoặc nếu nó đúng, nhưng điều đó đã được quy định trong quy tắc đoán đúng của chúng tôi được đề cập ở trên.)

  • Bây giờ, đặt giới hạn trên của công suất đầu tiên là 2 lớn hơn n (tức là số vừa đoán) và đặt giới hạn dưới của công suất 2 ngay bên dưới nó.

  • Lặp đi lặp lại đoán trung bình (làm tròn xuống) của giới hạn trên và giới hạn dưới. Nếu nó quá cao, đặt nó làm giới hạn trên. Nếu nó quá thấp, đặt nó làm giới hạn dưới. Thủ tục này được đảm bảo để cuối cùng dẫn đến một dự đoán chính xác.

Đây là một ví dụ, cho đầu vào của n = 21:

1 -> 2 -> 4 -> 8 -> 16 -> 32 -> 24 -> 20 -> 22 -> 21
\__________________________/
   repeated doubling      \________________________/
                             repeated averaging

Vì đây là , mã ngắn nhất tính bằng byte sẽ giành chiến thắng.

Dưới đây là tất cả các kết quả đầu ra từ n = 1 đến 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

Và đây là một số trường hợp thử nghiệm lớn hơn:

1234 -> 21
1337 -> 22
3808 -> 19
12345 -> 28
32768 -> 16
32769 -> 32
50000 -> 28

Câu trả lời:


10

Japt, 13 12 byte

Ôi trời ơi, tôi đã đánh bại cả Jelly và Pyth một thời gian: D

¢a1 ªJ +1+¢l

Kiểm tra nó trực tuyến!

Đây là chiến lược tôi sử dụng: gọi x là số nguyên đầu vào và để b là biểu diễn nhị phân của x . Đầu ra đúng là 1 + độ dài của b + chỉ số cuối cùng của a 1 trong b , trừ 1 nếu chỉ số này là 0.


2
Tôi đã nói với bạn Dennis sẽ thắng.
lirtosiast

7

Thạch, 18 15 10 9 byte

B>WU;BḄBL

Hãy thử trực tuyến! hoặc xác minh các trường hợp thử nghiệm nhỏcác trường hợp thử nghiệm lớn .

Lý lịch

Đặt n là số nguyên dương và m công suất nhỏ nhất bằng 2 lớn hơn hoặc bằng hoặc bằng n .

  • Các tăng gấp đôi giai đoạn mất một bước cho mỗi chữ số trong biểu diễn nhị phân của m .

  • Lấy biểu diễn nhị phân của n , loại bỏ chữ số đầu tiên, có ý nghĩa nhất (luôn luôn là 1 ) và tất cả các số 0 ở cuối. Các giai đoạn trung bình mất một bước cho mỗi chữ số còn lại.

Để tránh tính toán m , chúng tôi quan sát rằng, nếu n <m , số chữ số nhị phân của n chính xác bằng một số nhỏ hơn số chữ số nhị phân của m .

Nếu chúng ta thay thế chữ số nhị phân đầu tiên của n bằng 0 , đảo ngược kết quả, nối các chữ số nhị phân ban đầu và xóa tất cả các số 0 đứng đầu, thì điều sau sẽ xảy ra:

  • Nếu n là lũy thừa của 2 , tất cả các chữ số của một nửa (đã sửa đổi) đầu tiên sẽ bị xóa, chỉ còn lại các chữ số của biểu diễn nhị phân gốc của n = m .

  • Nếu nkhông một sức mạnh của 2 , các chữ số trong nửa đầu tiên tương ứng với chữ số quan trọng nhất không phải bị loại bỏ, thay thế cho những thực tế đó n có một chữ số nhị phân ít hơn m .

Làm thế nào nó hoạt động

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.

’B;Bt0L(7 byte) hoạt động trong phiên bản mới nhất của Jelly, sử dụng cách tiếp cận tương tự như trong câu trả lời Julia của tôi .
Dennis

4

ES6, 38 byte

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

Như được ám chỉ bởi các câu trả lời khác, bạn có thể tính toán số bước từ vị trí của các bit đầu tiên và cuối cùng.

Số lượng các bước trong giai đoạn nhân đôi là n=33-Math.clz32(x-1). Chúng tôi muốn 2ⁿ ≥ x nhưng n=33-Math.clz32(x)cho chúng tôi 2ⁿ> x để chúng tôi trừ 1 từ x để bù.

Số lượng các bước trong giai đoạn trung bình dễ dàng hơn, nó đơn giản n=Math.clz32(x&-x)-Math.clz32(x). x&-xlà một biểu thức tiện dụng đánh giá đến bit thấp nhất của x(như là lũy thừa của 2).


Làm thế nào để x&-xlàm việc? Tôi đã nghĩ rằng nó sẽ đánh giá giá trị tuyệt đối của x.
Sản xuất ETH

2
Tôi tìm thấy một lời giải thích tốt trên trang này (xem bit-hack # 7).
Sản xuất ETH

2

Bình thường, 15 13 byte

h-y.ElQ/PPyQ2

Tôi đã thấy rằng số cần tính là 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].

Hãy thử nó ở đây .


2

Julia, 37 35 byte

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

Cảm ơn @AlexA. để tiết kiệm 2 byte!

Điều này tuân theo các quan sát từ câu trả lời Jelly của tôi , nhưng xử lý khác với các trường hợp cạnh.

Nếu n> 1 , biểu diễn nhị phân của n - 1 có một chữ số nhỏ hơn một trong hai lũy thừa tiếp theo của 2 , được bù bằng cách không loại bỏ chữ số đầu tiên của biểu diễn nhị phân của n .

Bằng cách loại bỏ tất cả các số 0 từ cả hai phía , chúng tôi cũng xử lý trường hợp cạnh 1 .


0

Haskell, 82 byte

Đây là một triển khai khá đơn giản trong 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

Ít chơi gôn hơn:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.