이진 검색 단계 수


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

apt, 13 12 바이트

오 세상에 나는 젤리와 피스를 한동안 꺾었다. : D

¢a1 ªJ +1+¢l

온라인으로 테스트하십시오!

내가 사용하는 전략은 다음과 같습니다. x를 입력 정수로, bx 의 이진 표현으로합니다. 올바른 출력 + 1의 길이 (B) + (A)의 마지막 인덱스 1 에서 B 마이너스 1이 지수가 0 인 경우.


2
데니스가 이길 것이라고 했잖아
lirtosiast

7

젤리, 18 15 10 9 바이트

B>WU;BḄBL

온라인으로 사용해보십시오! 또는 작은 테스트 사례큰 테스트 사례를 확인하십시오 .

배경

n을 양의 정수로하고 mn 보다 크거나 같은 2 의 가장 작은 거듭 제곱으로 하자 .

  • 배로 위상의 바이너리 표현의 각 디지트를 하나씩 단계 얻어 m을 .

  • n 의 이진 표현을 취하고 가장 중요한 첫 번째 숫자 (항상 1 )와 모든 후행 0을 제거하십시오. 평균 위상 각 나머지 자리에 대해 하나의 단계를 더 걸린다.

계산 피하기 위해서는 m이 경우에, 우리는 그 관찰 N <m은 , 바이너리 숫자의 개수 N은 이하의 이진수의 개수보다 정확히 하나 m .

우리의 첫 번째 이진수 교체하는 경우 N을 으로 0 , 결과를 역 APPEND 원래 이진수 후 발생 다음, 모든 선행 0을 제거 :

  • 경우 n은 의 힘 , 모든 (변형)이 제 자리 절반의 원래의 이진 표현의 숫자 만 남기고 제거 얻을 N = m을 .

  • n2 의 거듭 제곱 이 아닌 경우 , 최상위 반 자리의 최상위 자릿수에 해당하는 숫자는 제거 되지 않으며 , nm 이하의 이진수 인 사실을 보상합니다 .

작동 원리

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 bytes)는 Julia answer 과 동일한 접근 방식을 사용하여 최신 버전의 Jelly에서 작동합니다 .
Dennis

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를 주므로 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 바이트 절약을 위해!

이것은 Jelly answer 의 관찰 결과를 따르지만 가장자리 사례와 다르게 처리됩니다.

n> 1 인 경우 , n-1 의 이진 표현은 2 의 다음 거듭 제곱보다 한 자릿수가 적습니다 . 이는 n 의 이진 표현의 첫 번째 숫자를 제거하지 않음으로써 보상됩니다 .

양쪽에서 모든 0 제거함으로써 우리는 에지 케이스 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.