バイナリ検索のステップ数


12

入力が正の整数の場合、1から始まるバイナリ検索で入力を見つけるために必要なステップ数を出力します。

入力として与えられた整数のバイナリ検索をシミュレートします。シミュレートされたサーチャーは整数を繰り返し推測し、整数が高すぎる、低すぎる、または正しいかどうかを確認できます。整数を見つけるための戦略は次のとおりです。

  • nを、検索しようとしている入力として与えられた整数とします。

  • 1の推測から開始します(推測ごとに(正しいかどうかに関係なく)ステップ数を増やし、推測が正しい場合は直ちにステップの合計数を停止して出力します。)

  • 推測がn(ターゲット数)よりも大きくなるまで繰り返し推測を繰り返します。(または、それが正しい場合でも、上記の正しい推測ルールで既にカバーされています。)

  • ここで、n(つまり、推測された数)よりも大きい2の最初の累乗の上限を設定し、その直下に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

オンラインでテストしてください!

私が使用する戦略は次のとおりです。xを入力整数とし、bxのバイナリ表現とします。正しい出力は、長さ1 +であるB +の最後のインデックス1におけるBこのインデックスが0である場合、マイナス1。


2
デニスが勝つと言った。
リルトシアスト

7

ゼリー、18 15 10 9バイト

B>WU;BḄBL

オンラインでお試しください!または、小さなテストケース大きなテストケースを確認します。

バックグラウンド

ましょNである正の整数、およびmは最小のパワー2大きいかと同等またはそれに等しいNを

  • 倍加相は、バイナリ表現中の各桁のワンステップかかりメートル

  • nのバイナリ表現を取得し、最初の最上位桁(常に1)とすべての後続ゼロを削除します。平均位相は、残りの各桁のための1つのステップを取ります。

計算避けるためにメートルをすれば、我々は、それを守ってN <Mは、バイナリの桁数nが少ないのバイナリ桁数よりも正確に一つですメートル

我々は最初の二進数交換した場合のnをして0結果を逆に、元のバイナリ数字を追加し、すべての先行ゼロを削除し、その後、次の処理が行われます。

  • 場合、nはの力である2全ての(変性)最初の桁は、半分の元のバイナリ表現の数字のみ残して、除去し得るN = Mを

  • n2のべき乗でない場合、最上位の桁に対応する前半の桁は削除されnm未満の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の最新バージョンで機能し、私のJulia answerと同じアプローチを使用します
デニス

4

ES6、38バイト

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

他の答えからもわかるように、最初と最後のビットの位置からステップ数を計算できます。

倍増段階のステップ数はですn=33-Math.clz32(x-1)。2ⁿ≥xが必要ですが、2ⁿ> xがn=33-Math.clz32(x)得られるため、xから1を引いて補正します。

平均化フェーズのステップ数は簡単で、単純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バイト節約します!

これは、私のゼリーの回答からの観察に従いますが、エッジケースの扱いが異なります。

n> 1の場合n-1の 2進表現の次の2の累乗よりも1桁少ないため、nの 2進表現の最初の桁を削除しないことで補正されます。

両側からすべてのゼロ削除することにより、エッジケースに対処します 1も処理します。


0

Haskell、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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.