이진 카운트 다운 길이


18

무한에서 카운트 다운에서 영감

음수가 아닌 정수가 주어지면 N0에 도달하는 데 필요한 다음 단계의 반복 횟수를 출력하십시오.

  1. N이진수로 변환 (4812390 -> 10010010110111001100110 )
  2. 각 비트 뒤집기 (10010010110111001100110 -> 01101101001000110011001 )
  3. 선행 0 자르기 (01101101001000110011001 -> 1101101001000110011001 )
  4. 십진수 ( 1101101001000110011001 -> 3576217)로 다시 변환

규칙

  • 입력과 출력은 모호하지 않고 일관된 형식 일 수 있습니다
  • 입력은 언어에 대해 표현 가능한 고유 정수 범위 내에 있습니다 (언어가 임의로 큰 정수를 지원하는 경우에는 경계가 없습니다)

테스트 사례

0 -> 0
1 -> 1
42 -> 6
97 -> 3
170 -> 8
255 -> 1
682 -> 10
8675309 -> 11
4812390 -> 14
178956970 -> 28
2863311530 -> 32

이 순서는 OEIS에서 A005811 입니다.


6
3 단계는 전혀
쓸모

@ edc65 알고리즘 배치 방법에 따라 3 단계 또는 4 단계를 수행 할 수있는 것 같습니다
Brian J

@ edc65 아마 당신에게 쓸모 가 없습니다. 간단한 역 연산자는 선행 0을 자르지 않습니다. ~(~a) == a
Poke

@Poke Bitwise NOT 은 선행 0을 포함한 모든 이진 표현의 비트 (임의의 정수는 임의의 정밀 정수를 사용하는 언어 )를 반전 시킵니다 . 이것은 2 단계와 동일하지 않습니다.
Dennis

@Poke 간단한 역 연산은 단계 1..4를 적용하는 것과 다릅니다. 이 단계를 적용하려면 단계 2의 플립 (표시된대로)이 선행 0을 변경하지 않으므로 단계 3은 사용되지 않습니다. 스텝 2는 경우 않는 최고의 1 초에 선도적 인 0을 변경 한 다음 obviuosly 당신은 최고의 제거해야 1 초를 ,하지의 주요 3 단계에서 0
edc65

답변:


14

젤리 , 6 4 바이트

^HBS

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

배경

n 은 음이 아닌 정수라고 하자 .

본 명세서에 기술 된 프로세스의 단계 2 및 3은 대안 적으로 모든 선행 1 을 제거 하고 나머지 비트를 토글 링하는 것으로 언급 될 수있다 .

의 바이너리 카운트 다운 길이, 그래서 우리는, 각 반복에 인접하고 평등 한 이진수 정확히 하나의 그룹을 제거거야이 수단 n은 의 이진 표현에서 이러한 그룹의 단지 수이다 N . 이 도전의 목적으로 0 은 숫자가없는 것으로 생각하십시오 .

들면 N = 8,675,309 , 프로세스 보이는 진 다음.

100001000101111111101101
 11110111010000000010010
     1000101111111101101
      111010000000010010
         101111111101101
          10000000010010
           1111111101101
                   10010
                    1101
                      10
                       1
                       0

이러한 그룹을 세는 대신 (가장자리 0에서는 실패 ) 다음을 수행합니다.

nn : 2 에는 다음 이진 표현이 있습니다.

n   = 8675309 = 100001000101111111101101_2
n:2 = 4337654 =  10000100010111111110110_2

참고 N : 2 의 이진 표현은 단순히 N 들 ', 왼쪽에 하나 개의 비트를 이동했다.

XOR nn : 2 이면 1 (MSB)과 서로 다른 인접한 숫자 쌍마다 1 을 추가로 얻습니다 . 따라서 그룹의 수는 n ⊻ n : 2 의 설정 비트 수와 같습니다. .

작동 원리

^HBS  Main link. Argument: n

 H    Halve; yield n:2.
^     XOR n with n:2.
  B   Convert the result to binary.
   S  Compute the sum of the resulting binary digits.

1
놀랄 만한! 완전히 다른 추론
edc65

9

파이썬 2, 30 바이트

lambda n:bin(n^n/2).count('1')

Ideone에서 테스트하십시오 .

배경

n 은 음이 아닌 정수라고 하자 .

본 명세서에 기술 된 프로세스의 단계 2 및 3은 대안 적으로 모든 선행 1 을 제거 하고 나머지 비트를 토글 링하는 것으로 언급 될 수있다 .

의 바이너리 카운트 다운 길이, 그래서 우리는, 각 반복에 인접하고 평등 한 이진수 정확히 하나의 그룹을 제거거야이 수단 n은 의 이진 표현에서 이러한 그룹의 단지 수이다 N . 이 도전의 목적을 위해 0을 생각하십시오 은 숫자가없는 것으로 .

들면 N = 8,675,309 , 프로세스 보이는 진 다음.

100001000101111111101101
 11110111010000000010010
     1000101111111101101
      111010000000010010
         101111111101101
          10000000010010
           1111111101101
                   10010
                    1101
                      10
                       1
                       0

이러한 그룹을 세는 대신 (가장자리 0에서는 실패 ) 다음을 수행합니다.

nn : 2 에는 다음 이진 표현이 있습니다.

n   = 8675309 = 100001000101111111101101_2
n:2 = 4337654 =  10000100010111111110110_2

참고 N : 2 의 이진 표현은 단순히 N 들 ', 왼쪽에 하나 개의 비트를 이동했다.

XOR nn : 2 이면 1 (MSB)과 서로 다른 인접한 숫자 쌍마다 1 을 추가로 얻습니다 . 따라서 그룹의 수는 n ⊻ n : 2 의 설정 비트 수와 같습니다 .


9

파이썬 2, 29 바이트

f=lambda n:n and-n%4/2+f(n/2)

이진 확장에서 0과 1 사이의 교번 수를 계산하고 선행 1을 교대로 계산합니다. 마지막 두 이진 숫자가 다른지 확인한 다음 마지막 숫자를 제거한 숫자로 되풀이합니다. 마지막 두 자리 n%4는 1 또는 2 인 경우 정확하게 다르며 로 확인할 수 있습니다 -n%4/2.


6

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

f=n=>n&&(n^(n>>=1))%2+f(n)

0과 1 사이의 전환을 계산하여 작동합니다. 최대 31 비트 만 작동합니다. 53 비트를 지원하는 29 바이트 :

f=n=>1<=n&&(n%2^n/2%2)+f(n/2)

5

하스켈, 34 바이트

b 0=0
b n|x<-b$div n 2=x+mod(x+n)2

"0 = 0"이라고 말하는 방식이 마음에
듭니다.


3

CJam , 14 바이트

ri0{2b:!2bj)}j

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

ri      e# read integer
0       e# value for terminal case
{       e# recursive function
  2b    e#   create binary representation with no leading zeros
  :!    e#   flip bits
  2b    e#   convert binary back to integer
  j     e#   recursive call
  )     e#   increment from 0 on the way up
}j      e# end

기본적으로 다른 질문에 대한 나의 대답 은 무너졌습니다 .


3

자바 7,112108100 90 73 바이트

int c(int i){int l=1,j=i;for(;(j=j/2)>0;l*=2);return i<1?0:1+c(2*l-1-i);}

기본 아이디어

 Lets take an no 10110(21)
 then you do set all bits in no 21 and you will get 11111
 and after that you would subtract the original number from 11111.
 You will get 01001 and loop it until you will get 0

j=j/2로 단축 할 수 있습니다 j/=2. 그 외에도 좋은 대답입니다!
Kevin Cruijssen

흠 .. @Neil 의 JavaScript 응답 포트는 int c(int i){return i>0?((i^(i>>=1))%2+c(i):0;}( 47 바이트 ) 짧습니다 . 더 독창적이며 다른 사용자의 포트는 원본과 완전히 반대이기 때문에 여전히 현재 답변을 남겨 두겠습니다. :)
Kevin Cruijssen

3

J, 14 바이트

**1+/@,2~:/\#:

n = 0에 대해 0을 반환하는 특수한 경우로 n 의 2 진수 숫자로 실행 횟수를 계산합니다 .

용법

   f =: **1+/@,2~:/\#:
   (,.f"0) 0 1 42 97 170 255 682 8675309 4812390 178956970 2863311530
         0  0
         1  1
        42  6
        97  3
       170  8
       255  1
       682 10
   8675309 11
   4812390 14
 178956970 28
2863311530 32

설명

**1+/@,2~:/\#:  Input: integer n
            #:  Get the binary digits of n
       2   \    For each overlapping sublist of size 2
        ~:/       Reduce by not-equals
  1   ,         Prepend a 1
   +/@          Reduce by addition
*               Sign(n), returns 0 for n = 0 else 1
 *              Multiply with the previous sum and return

3

CJam , 11 10 바이트

1 바이트를 절약 해 준 @Dennis에게 감사드립니다!

ri_2be`,e&

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

설명

ri            #e Read as integer
              #e STACK: 97
  _           #e Duplicate
              #e STACK: 97, 97
   2b         #e Convert to binary
              #e STACK: 97, [1 1 0 0 0 0 1]
     e`       #e Run-length encoding
              #e STACK: 97, [[2 1] [4 0] [1 1]]
       ,      #e Length
              #e STACK: 97, 3
        e&    #e Return first value if 0, or else the second value
              #e STACK: 3

1
e&(논리 AND)는 바이트를 저장합니다 \g*.
Dennis

@Dennis 감사합니다! CJam의 논리 AND 작품, 나는 아무 생각도 없었다 방법이 편리합니다
루이스 Mendo

2

라켓 349 바이트

(define(h s)(apply string(map(λ(x)(if(eq? x #\0)#\1 #\0))(string->list s))))(define(g s)(let*
((l(string-length s))(k(for/list((i s)(n l)#:final(not(equal? i #\0)))n)))(substring s(last k))))
(define(f n)(if(= 0 n)0(begin(let loop((n n)(c 1))(define m(string->number(string-append "#b"
(g(h(number->string n 2))))))(if(> m 0)(loop m(add1 c))c))))

언 골프 드 :

(define (invertBinary s)
  (apply string
         (map
          (λ(x)(if(eq? x #\0)#\1 #\0))
          (string->list s))))

(define (trimLeading0s s)
  (let* ((l (string-length s))
         (k (for/list ((i s)
                       (n l)
                       #:final (not(equal? i #\0)))
              n)))
    (substring s (last k))))

(define (f n)
  (if (= 0 n) 0
      (begin
        (let loop ((n n)
                   (c 1))
          (define m 
            (string->number
             (string-append
              "#b"
              (trimLeading0s
               (invertBinary
                (number->string n 2))))))

          (if (> m 0)
              (loop m (add1 c))
              c)))))

테스트 :

(f 0)
(f 1)
(f 42)
(f 97)
(f 170)
(f 255)
(f 682)
(f 8675309)
(f 4812390)
(f 178956970)
(f 2863311530)

산출:

0
1
6
3
8
1
10
11
14
28
32

tlib1 바이트 이름을 변경 하여 2 바이트를 저장할 수 있습니다 .
Mego

끝난. 제안 해 주셔서 감사합니다.
rnso

2

MATL , 7 바이트

BY'nwa*

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

설명

          % Implicit input, for example 97
          % STACK: 97
B         % Convert to binary
          % STACK: [1 1 0 0 0 0 1]
 Y'       % Run-length encoding
          % STACK: [1 0 1], [2 4 1]
   n      % Number of elements
          % STACK: [1 0 1], 3
    w     % Swap
          % STACK: 3, [1 0 1]
     a    % Any: gives 1 if any element is nonzero
          % STACK: 3, 1
      *   % Multiply
          % STACK: 3
          % Implicit display

2

Vim, 62 59 바이트

DJMcMayhem 덕분에 -3 바이트

C0
<C-r>=pri<Tab>'%b',<C-r>")
<Esc>0qqC<C-r>=tr(@",'01','10')
<Esc>:s/^0\+
k<C-a>j@qq@q

인쇄 할 수없는 문자가 그대로있는 xxd 출력은 다음과 같습니다.

0000000: 4330 0d12 3d70 7269 0927 2562 272c 1222  C0..=pri.'%b',."
0000010: 290d 1b30 7171 4312 3d74 7228 4022 2c27  )..0qqC.=tr(@",'
0000020: 3031 272c 2731 3027 290d 1b3a 732f 5e30  01','10')..:s/^0
0000030: 5c2b 0d6b 016a 4071 7140 71              \+.k.j@qq@q

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

설명

C                                   " Delete the number (it goes in @")
0<CR>                               " Print 0 (our counter) and a carriage return
<C-r>=pri<Tab>'%b',<C-r>")<CR><Esc> " Use `printf()` to insert the number as base 2
0qq                                 " Return to column 0, start recording a macro
  C<C-r>=tr(@",'01','10')<CR><Esc>  "   Replace 0s with 1s and vice versa
  :s/^0\+<CR>                       "   Delete leading 0s
  k<C-a>                            "   Increment the number on the line above
  j                                 "   Return to the previous line
  @q                                "   Invoke macro recursively
q@q                                 " Stop recording and invoke macro

1
좋은! 몇 가지 팁 : :s/^0*은 1 바이트보다 짧으며 :s/^0\+"eval"레지스터에있는 pr<S-tab>'%b',<C-r>")동안 자동 완성을 위해 할 수 있습니다 . (4 바이트 저장)
DJMcMayhem

오, 자동 완성 팁에 감사드립니다! :s/^0*빈 줄과 일치 하기 때문에 사용할 수 없으며 빈 줄을 비워서 재귀 매크로를 이스케이프 처리 하지 않아야합니다 .
요르단

1

루비, 26 바이트

f=->n{n<1?0:-n%4/2+f[n/2]}

xnor의 Python 답변에서 영감을 얻었습니다.


0

PHP, 64 바이트

내 카운트 다운 솔루션을 기반으로

for($n=$argv[1];$n;print 1)$n=bindec(strtr(decbin($n),"01",10));

반복 횟수가있는 1문자 k시간을 인쇄 합니다 k.


정수 출력의 경우 +4 바이트 : (의 경우 빈 출력 0)

for($n=$argv[1];$n;$i++)$n=bindec(strtr(decbin($n),"01",10));echo$i;

0

자바 스크립트 (ES6), 44

재귀 함수

자바 스크립트 양의 정수로 제한, 31 비트 :

f=(a,s=0)=>a?f((-1>>>Math.clz32(a))-a,s+1):s

최대 53 개의 유효 비트 -59 바이트의 배정도 숫자 관리 :

F=(a,s=0)=>a?F('0b'+a.toString(2).replace(/./g,1)-a,s+1):s

다른 방법으로 : @Dennis의 놀라운 알고리즘을 사용하여 53 비트, 43 바이트를 비 재귀 함수로 관리합니다 .

a=>a&&a.toString(2).match(/(.)\1*/g).length

0

PHP, 51 바이트

<?=preg_match_all('/(1+|0+)/',decbin($argv[1])?:o);

정규 표현식을 사용하여 1 또는 0의 런 수를 계산합니다. 불행히도 이것은 입력을 위해 특별한 경우 03 바이트가 필요하며 통지합니다.


a) o통지를 피하기 위해 숫자> 1을 사용하십시오 . b) 대신 -F플래그와 함께 3 바이트를 저장할 수 있습니다 . c) 정규식에 충분해야한다. $argn$argv[1]/1+|0+/
Titus


0

옥타브, 47 바이트

@(x)(sum(dec2bin(bitxor(x,idivide(x,2)))=='1'))

OEIS 항목에 따르면, 우리는이 문제의 해결책이 같이 찾고있는 값 도이 수와 동일한 1지정된 정수의 그레이 코드의.

Wikipedia는 그레이 코드를 x ^ (x >> 1)로 계산할 수 있다고 알려주므로 위 함수에서 그레이 코드를 계산하고 이진 문자열로 변환하고 해당 문자열의 자릿수를 계산합니다 1.



0

C, 76 바이트

unsigned n,m,i;f(x){for(i=0;x;x^=m-1,i++)for(n=x,m=2;n>>=1;m<<=1);return i;}

모든 테스트 사례에서 작동합니다 (서명되지 않은 단어 또는 마지막 테스트 사례를 포함하고 싶지 않은 한) ...


0

배쉬, 57 바이트

패키지 : 코어 유틸리티, grep, sed, vim (for xxd )

숫자가 이진 형식으로 주어진다고 가정하십시오. 모든 길이는 허용됩니다 :)

xxd -b -c1|cut -d" " -f2|sed s/^0*//|grep -o .|uniq|wc -l


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.