Кількість кроків для двійкового пошуку


12

З огляду на введення додатного цілого числа, виведіть кількість кроків, які потрібно здійснити, щоб знайти вхід через двійковий пошук, починаючи з 1.

Ми моделюємо двійковий пошук цілого числа, яке було задано у якості вводу, в якому змодельований шукач може багаторазово відгадувати ціле число і йому відповісти, чи він занадто високий, занадто низький чи правильний. Стратегія пошуку цілого числа така:

  • Нехай n - ціле число, подане як вхід, який ми намагаємося знайти.

  • Почніть з здогадки з 1. (Для кожної здогадки збільште кількість кроків (незалежно від того, правильна вона чи ні), і негайно зупиніть та виведіть загальну кількість кроків, якщо здогадка була правильною.)

  • Подвійне здогадку повторно, поки здогадка не перевищує n (цільове число). (Або, якщо це правильно, але це вже охоплено нашим правилом правильної здогадки, згаданим вище.)

  • Тепер встановіть верхню межу першої потужності на 2, яка більша за n (тобто число, що було тільки здогадано), і встановіть нижню межу потужності 2 безпосередньо під нею.

  • Неодноразово відгадуйте середнє значення (округлене вниз) верхньої та нижньої межі. Якщо вона занадто висока, встановіть її як верхню межу. Якщо він занадто низький, встановіть його як нижню межу. Ця процедура гарантовано, що врешті-решт приведе до правильної здогадки.

Ось приклад для введення n = 21:

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

Оскільки це , найкоротший код у байтах виграє.

Ось усі результати від n = 1 до 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

Ось кілька великих тестових випадків:

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

Відповіді:


10

Japt, 13 12 байт

О боже, я якийсь час бив і Джелі, і Піта: D

¢a1 ªJ +1+¢l

Перевірте це в Інтернеті!

Ось застосування стратегії I: нехай х буде вхідний ціле число, і нехай б бути х «s двійкове подання. Правильний вихід - 1 + довжина b + останній індекс 1 в b , мінус 1, якщо цей показник дорівнює 0.


2
Я сказав вам, що Денніс переможе.
lirtosiast

7

Желе, 18 15 10 9 байт

B>WU;BḄBL

Спробуйте в Інтернеті! або перевірити малі тестові та великі тестові випадки .

Фон

Нехай n - натуральне ціле число, а m найменша потужність 2, яка більша або дорівнює n або дорівнює n .

  • Подвоєння фази приймає один крок для кожної цифри в двійковому поданні м .

  • Візьміть двійкове подання n , видаліть першу, найбільш значущу цифру (завжди 1 ) і всі проміжні нулі. Фаза усереднення приймає один крок для кожної залишилася цифри.

Щоб уникнути обчислення m , ми зауважимо, що, якщо n <m , кількість двійкових цифр n точно на одну меншу, ніж число двійкових цифр m .

Якщо ми замінимо першу двійкову цифру n на 0 , повернемо результат, додамо початкові двійкові цифри та видалимо всі провідні нулі, тоді станеться таке:

  • Якщо n - потужність 2 , всі цифри першої (модифікованої) половини вилучаються, залишаючи лише цифри вихідного двійкового зображення n = m .

  • Якщо п є НЕ ступінь 2 , цифра в першій половині , що відповідає найбільш значущої цифри ніяк НЕ видаляються, компенсуючи тим , що п має двійкову цифру менше , ніж т .

Як це працює

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 байт) працює в останній версії Jelly, використовуючи той самий підхід, як у моїй відповіді Джулії .
Денніс

4

ES6, 38 байт

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

Як наводиться на інші відповіді, ви можете обчислити кількість кроків з позицій першого і останнього бітів.

Кількість етапів у фазі подвоєння становить n=33-Math.clz32(x-1). Ми хочемо 2ⁿ ≥ x, але n=33-Math.clz32(x)дає нам 2ⁿ> x, тому віднімаємо 1 від x для компенсації.

Кількість етапів у фазі усереднення простіше, просто n=Math.clz32(x&-x)-Math.clz32(x). x&-x- зручний вираз, який оцінюється до найнижчого розряду x(як сила 2).


Як x&-xпрацює? Я б подумав, що вона буде оцінена до абсолютного значення x.
ETHproductions

2
Я знайшов гарне пояснення на цій сторінці (див. Біт-хак №7).
ETHproductions

2

Pyth, 15 13 байт

h-y.ElQ/PPyQ2

Я виявив, що число, яке потрібно обчислити, є 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].

Спробуйте тут .


2

Джулія, 37 35 байт

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

Завдяки @AlexA для економії 2 байтів!

Це випливає зі спостережень з моєї відповіді Jelly , але по-різному стосується кращих випадків.

Якщо n> 1 , двійкове подання n - 1 має одну цифру менше, ніж наступну потужність 2 , що компенсується не видаленням першої цифри двійкового подання n .

Видаляючи всі нулі з обох сторін , ми також маємо справу з крайовим випадком 1 .


0

Хаскелл, 82 байти

Це досить просто реалізація в 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

Менше гольфу:

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.