태그 보관물: number

number

정수의 디지털 경도 , 이진 표현

정수 의 디지털 경도 를 찾으려면 이진 표현을 취하고으로 시작하거나 끝날 때까지 선행 후행 1을 제거 할 수있는 횟수를 계산하십시오 0. 제거 된 총 비트 수는 디지털 경도입니다.

그것은 꽤 간결한 설명입니다. 잘 작동하는 예를 들어 보겠습니다.

이 예에서는 숫자 3167을 사용합니다. 이진수로 다음과 같습니다.

110001011111

(이진수로 변환하는 동안 선행 0을 제거해야합니다.)

로 시작하거나 끝나지 0않으므로 1 쌍의 비트를 제거합니다.

1  1000101111  1

그리고 또 다른:

11  00010111  11

그러나 이제 시작 부분에 0이 있으므로 더 이상 1쌍을 제거 할 수 없습니다 . 총 4 비트를 제거 했으므로 43167 의 디지털 경도입니다 .

그러나 양수 n (즉 , 이진 표현 에만 포함)에 대해 2 n -1 로 쓸 수있는 숫자의 경우 0에 도달하지 않으므로 모든 비트를 제거 할 수 있습니다. 이것은 경도가 단순히 정수의 비트 길이라는 것을 의미합니다.1


도전

음수가 아닌 정수가 주어지면 n >= 0디지털 경도를 결정 하는 프로그램이나 함수를 작성해야합니다 .

I / O를 수행하는 전체 프로그램 또는 결과를 반환하는 함수를 제출할 수 있습니다. 귀하의 제출물은 n귀하의 언어의 표준 정수 범위 내의 값으로 작동해야 합니다.


테스트 사례

이 중 하나라도 부정확하거나 추가 할 엣지 케이스를 제안하려면 알려주십시오.

0     -> 0
1     -> 1
8     -> 0
23    -> 2
31    -> 5
103   -> 4
127   -> 7
1877  -> 2
2015  -> 10

다음은 이러한 테스트 사례를 생성하는 데 사용 된 ungolfed Python 솔루션입니다 (버그가없는 것으로 보장되지는 않음).

def hardness(num) -> int:
    binary = bin(num)[2:]

    if binary.count('0') == 0:
        return num.bit_length()

    revbin = binary[::-1]

    return min(revbin.find('0'), binary.find('0')) * 2


답변

젤리 , 11 10 바이트

BµQL××Ṛa\S

온라인으로 사용해보십시오!

작동 원리

BµQL××Ṛa\S  Main link. Argument: n

B           Binary; convert n to base 2.
 µ          Begin a new, monadic chain. Argument: A (array of binary digits)
  Q         Unique; deduplicate the digits.
   L        Length; count the unique digits.
    ×       Multiply each digit by the result.
     ×Ṛ     Multiply the results by reversed A.
       a\   Cumulative reduce by logical AND.
            This zeroes out all elements after the first zero.
         S  Compute the sum of the result.

답변

파이썬 , 76 69 68 63 62 60 57 바이트

f=lambda n,k=0:n>>k&(n&n>>k>n>>k+1)and(n&n+1>0)-~f(n,k+1)

온라인으로 사용해보십시오!

작동 원리

이것은 입력을 받아 재귀 해결책 N 및 증분 유지 K 에서 시작 – 0 – 동안 모두 LSB K (N) (비트 인덱스에서 K 오른쪽)와 MSB의 K (N) (인덱스의 비트 K 왼쪽) 설정됩니다. 완료되면 모든 n 비트가 설정 되면 k를 반환 하고 그렇지 않으면 2k를 반환합니다.

보조 변수 t를 사용 하여 람다 f 를 명명 된 함수 F 로 다시 작성해 봅시다 .

def F(n, k = 0):
    t = n >> k
    return t & (n & t > t >> 1) and (n & (n + 1) > 0) + 1 + F(n, k + 1)

각 호출에 F , 첫번째 비트 시프트 우리 N 개의 케이 우측 부와의 결과 저장 t를 . 이런 식으로 LSB 0 (t) = LSB k (n) 이므로 LSB k (n) 이 설정된 경우에만 t 가 홀수 입니다.

MSB k (n)의 설정 여부를 결정하는 것은 약간 까다 롭습니다. 이것이 n & t > t >> 1달성하는 것입니다. 그것이 어떻게 작동하는지 설명하기 위해 비트 길이 8 의 정수 n = 1αβγδεζη 2 를 고려 하고 함수 호출 F (n, 3) , 즉 k = 3을 분석해 봅시다 .

우리는 비교의 진실 값 (n & t> t >> 1) = (1αβγδεζη 2 & 1αβγδ 2 > 1αβγ 2 ) 을 조사하여 MSB 3 (n) = γ 가 설정되어 있는지 확인하려고합니다 . 관련된 정수를 살펴 보자.

MSB-index  012k4567

n          1αβγδεζη
t             1αβγδ

t >> 1         1αβγ

n & t> t >> 1 인 경우에만 γ = 1 이라고 주장합니다 .

  • 만약 γ = 1 다음, n은 t가 비트 길이 갖는 5 동안 t >> 1 비트 길이를 갖는 4 이므로 n은 t> t >> 1 .

    이는 γ = 1이 n & t> t >> 1 임을 의미 합니다.

  • 경우 n은 t> t >> 1 , 두 가지가있다 : 하나 γ = 1 또는 γ = 0 . 첫 번째 경우에는 증명할 것이 없습니다.

    두 번째 경우에는 αβγδ 2 ≥ n & t> t >> 1 = 1αβγ 2 입니다.

    이후 αβγδ 2 > 1αβγ 2 우리가 있어야 MSB 0 (αβγδ 2 ) MSB ≥ 0 (1αβγ 2 ) , 즉 저 α = 1 .

    이런 식으로 1βγδ 2 > 11βγ 2 이므로 MSB 1 (1βγδ 2 ) ≥ MSB 1 (11βγ 2 )을 가져야 합니다. 즉, β = 1 입니다.

    차례로, 이는 11γδ 2 > 111γ 2를 의미합니다 . 두 번째 경우에 γ = 0 임을 기억 하면 부등식 110δ 2 > 1110 2를 얻습니다 . 이는 MSB 2 (110δ 2 ) = 0 <1 = MSB 2 (1110 2 ) 이므로 false 입니다.

    따라서 첫 번째 경우 만 가능하며 n & t> t >> 1은 γ = 1을 의미 합니다.

요약하면 LSB k (n)MSB k (n) 이 모두 설정되면 t 는 홀수이고 n & t> t >> 1True 가되므로 t & (n & t> t >> 1) 은 수율 1 . 그러나 LSB k (n) 또는 MSB k (n) 이 설정되지 않은 경우 (또는 둘 다인 경우), t 는 짝수이거나 n & t> t >> 1False 이므로 t & (n & t> t> > 1)0이 됩니다.

단일 인수로 F 를 호출 하면 k = 0이 초기화 됩니다. 앞에서 논의한 조건이 유지되는 동안, 이후의 코드 and가 실행되는데 ,이 코드 는 (다른 것들 중에서) 증가 된 k로 F 를 재귀 적으로 호출합니다 .

일단 LSB K (N) 또는 MSB의 K (N)가 해제되면, 조건이 실패하고 F가 (N, K)를 반환 0 . 앞의 k 함수 호출 각각은 (n & (n + 1)> 0) + 1F (n, k) = 0 을 더하므로 F (n)((n & (n + 1)> 0) + 1) k .

이제 n의 모든 비트 가 같으면 (즉, n0 이거나 모든 비트가 설정된 경우) n + 1n 과 공통 인 비트를 가지지 않으므로 n & (n + 1) = 0 이고 F (n)k를 반환합니다 . 그러나 n 에 설정 및 설정 해제 비트가 모두 있으면 n & (n + 1)> 0 이고 F (n)2k를 반환합니다 .


답변

MATL , 13 12 바이트

Btv`6L&)}x@q

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

설명

이 코드는 각 이진수를 반복하고 두 개의 외부 숫자를 제거 할 수있는 횟수를 계산합니다.

B        % Input number (implicit). Horizontal vector of binary digits
tv       % Duplicate and concatenate vertically
`        % Do...while
  6L&)   %   Flatten the array if needed (in column-major order), and split it
         %   into two subarrays: one with the inner entries, and another
         %   with the two outer entries. The latter will be used for deciding
         %   if the loop continues or is exited
}        % Finally (execute before exiting the loop)
  x      %   Delete last subarray of inner entries
  @q     %   Push last iteration index minus 1
         % End (implicit). The next iterarion is executed if the array at the
         % top of the stack is non-empty and only contains nonzero values.
         % Otherwise the loop is exited, executing the "finally" block first
         % Display (implicit)

답변

파이썬, 82 바이트

나는 아직도 골프를 칠 수 있다고 생각하지만 다른 방법을 시도하는 데 시간을 보냈으며 이것이 가장 짧았습니다.

def f(n):b=bin(n)[2:];x=min(b.find('0'),b[::-1].find('0'));print(x<0)*len(b)or x*2

온라인으로 사용해보십시오

이것은 OP의 Python 프로그램과 유사하게 작동하지만 Sandbox에서 질문을 본 후에 그러한 프로그램이 포함되지 않은 질문을 게시하기 전에 이것을 만들었습니다.


답변

파이썬 2, 66 바이트

s=bin(input())[2:].split('0')
print len(min(s[-1],s[0]))<<1%len(s)

입력의 이진 표현을 1의 청크로 나눕니다. 첫 번째 청크와 마지막 청크 중 작은 것에서 1의 수를 세고 두 번 계산하는 단일 청크가 없으면 두 배로합니다.


답변

PowerShell , 109106 바이트

$a=[convert]::ToString($args[0],2)-split0;(((($b=$a[0].length),$a[-1].length|sort)[0]*2),$b)[$a.count-eq1]

온라인으로 사용해보십시오!

input $args[0]을 가져 convert와서 .NET 호출을 toStringbase 2(즉, 이진으로)로 사용 한 다음 -split해당 문자열을 0s에 저장합니다 $a. 주의 사항 : .NET 호출은 선행 0을 반환하지 않으므로 첫 번째 숫자는 항상입니다 1.

따라서 이진 문자열은 모두 1이거나 적어도 하나의 0이 있습니다. 우리는에 의해 의사 의사 삼진을 가진 사람들을 구별합니다 $a.count-eq1. 진 하나 이상의 제로, 왼쪽 케이스가있는 경우, 우리는 첫 번째의 길이의 최소 걸릴 [0]문자열 1의 마지막 [-1]문자열을 (발견 |sort[0]). 그 중 더 짧은 것은 우리가 제거 할 수있는 가장 많은 쌍이므로, 우리는 그것을 곱합니다 2. A의 원래 바이너리 문자열 끝이 경우주의 0, 입력처럼 8, 다음은 [-1].length도있을 것입니다 0곱한 (가 빈 문자열을 이후) 2아직 0.

그렇지 않으면 이진 문자열을 모두 사용하면 방금 가져 $b옵니다 (이전에 첫 번째 [0]문자열 의 길이 ,이 경우 이진 문자열의 전체 길이로 설정 됨 ).

두 경우 모두 해당 결과가 파이프 라인에 남아 있고 출력이 암시 적입니다.


답변

자바 스크립트 (ES6), 57 바이트

f=
n=>n.toString(2).replace(/^(1*)(.*(\1))?$/,'$1$3').length
<input oninput=o.value=1/this.value?f(+this.value):''><input id=o readonly>

이진을 취하여 1s같은 수의 선행 및 후행과 일치 하거나 모두 실패합니다 1s.