부호없는 16 비트 정수에서 1의 수를 센다


24

부호없는 16 비트 정수로 된 수를 세는 문장을 작성하십시오.

예를 들어, 입력이 인 경우 16 비트 이진수 는 6 개를 포함 하는 16 비트 이진수 이므로 1337결과가 나타납니다 .613370000010100111001


2
팁 : 숫자의 일부 숫자가 숫자 mod 9와 일치하는 것처럼 일부 비트는 숫자 mod 1과 같습니다.
— PyRulez

8
@PyRulez 모든 숫자는 0 모듈로 1입니다.
— Thomas

1
안녕하세요, 당신은 잘못된 답변을 수락 된 답변으로 선택했습니다 (기본적으로 가장 이른 포스트의 타이 브레이커 로직).
— Optimizer

4
@ 토마스 나는 그것이 유용한 팁이라고 결코 말하지 않았다.
— PyRulez

2
대부분의 답변이 게시 된 후에 왜이 질문에 대한 투표가 활발합니까? 가까운 유권자들은 귀하의 이유를 의견에 기재하십시오. 표준 허점을 준수하지 않는 es1024의 (매우 영리한) 4 바이트 응답을 승인하는 경우 (내장 사용) 이것이 이유라고 설명하십시오. 그렇지 않으면 무엇입니까?
— Level River St

답변:


37

80386 머신 코드, 4 바이트

F3 0F B8 C1

정수를 가져 와서 cx카운트를 출력하며 다음 ax과 같습니다.

popcnt ax, cx     ; F3 0F B8 C1

POPCNT를 사용하지 않는 11 10 바이트 솔루션 은 다음과 같습니다 .

31 C0 D1 E9 10 E0 85 C9 75 F8

이는 다음과 같습니다.

xor ax, ax        ; 31 C0   Set ax to 0
shr cx, 1         ; D1 E9   Shift cx to the right by 1 (cx >> 1)
adc al, ah        ; 10 E0   al += (ah = 0) + (cf = rightmost bit before shifting)
test cx, cx       ; 85 C9   Check if cx == 0
jnz $-6           ; 75 F8   Jump up to shr cx, 1 if not

이것이 32 비트 또는 16 비트 (실제 또는 보호) 모드입니까?
— FUZxxl

2
어셈블리가 제공 @FUZxxl를 교체하지만, 16 비트위한 ax와 cx함께 eax및 ecx32 비트를 변경한다. 바이트 코드도 동일합니다.
— es1024

1
@ es1024 바이트 코드는 16 비트 모드로 컴파일되고 32 비트 버전은 32 비트 모드로 컴파일 된 경우 동일 합니다.
— Cole Johnson

2
popcnt가 내장되어 표준 허점의 파울이 아닙니까? 그래도 두 번째 솔루션에 대한 신용.
— Alchymist

5
기계 코드 의 길이를 주장 할 때 제목이 "80386 어셈블러"가 아니라 "80386 기계 코드"가 아니어야합니까?
— 케빈 리드

14

파이썬 2, 17 바이트

bin(s).count('1')

bin내장 반환 정수 이진 문자열로 변환. 그런 다음 1숫자 를 계산합니다 .

>>> s=1337
>>> bin(s)
'0b10100111001'
>>> bin(s).count('1')
6

11

J (5 자)

J에는 명시적인 유형이 없습니다. 이것은 모든 정수에 대해 올바른 일을합니다.

+/@#:
  • +/ 합계
  • @ 의
  • #: 기본 두 표현

11

C, 21

for(n=0;x;n++)x&=x-1;

"함수"가 아닌 "일부 명령문 작성"이라고 말 했으므로 숫자가 제공되고 x1이 반환 된다고 가정 했습니다 n. 초기화 할 필요가 없으면 n3 바이트를 절약 할 수 있습니다.

이것은 x&x-1무언가가 2의 거듭 제곱인지 테스트 하는 유명한 표현 을 수정 한 것입니다 (그렇지 않으면 거짓, 그렇지 않으면 참).

여기서 그것은 질문의 번호 1337에 적용됩니다. 1을 빼면 최하위 1 비트와 모든 0이 오른쪽으로 반전됩니다.

0000010100111001 & 0000010100111000 = 0000010100111000
0000010100111000 & 0000010100110111 = 0000010100110000
0000010100110000 & 0000010100101111 = 0000010100100000
0000010100100000 & 0000010100011111 = 0000010100000000
0000010100000000 & 0000010011111111 = 0000010000000000
0000010000000000 & 0000001111111111 = 0000000000000000

편집 : 완전성을 위해 여기에 순진 알고리즘이 있습니다.이 알고리즘은 1 바이트 더 길고 약간 느립니다.

for(n=0;x;x/=2)n+=x&1;


1
@ edc65가 나왔으므로 바퀴를 다시 발명했습니다. 적어도을 생략하여 2 바이트를 절약했습니다 {}. 누군가가 이미 생각 해낸 것에 놀라지 말아야 할 간단한 작업입니다.
— Level River St

"1960 년에 처음 출판 됨" 인상적.
— mbomb007

순진한 알고리즘으로 수정 :for(n=0;x;x/=2)n+=x&1;
— Helios

1
@nmxprime OP가 부호없는 int를 요청합니다. 내 32 비트 컴파일러에서 -7 = 11111111 11111111 11111111 11111001의 경우 빠른 알고리즘에 대해 30을 얻습니다. 순진 알고리즘의 경우 -7, -7 / 2 = -3, -3 / 2 = -1, -1 / 2 = 0을 반복합니다. 그것은 잘못된 대답을 제공합니다. x / = 2를 x >> = 1로 변경하면 일부 컴파일러에서 정답을 얻을 수 있지만 음수에서 >>에 대해 1 또는 0이 빈 비트로 이동되는지 여부에 대해서는 C가 정의되지 않습니다. 1을 바꾸는 컴파일러는 무한 루프로 들어갑니다. 해결 방법은 x를 부호없는 정수로 정의하는 것입니다. 그런 다음 x = -7은 (1 << 32) -7 = 4294967289를 x에로드합니다.
— Level River St

5

비경쟁 젤리

이 답변은 도전 과제가 게시 된 후 언어가 생성되었으므로 경쟁이 아닙니다.

2 바이트 :

BS

Jelly는 @Dennis가 J와 유사한 구문으로 작성한 새로운 언어입니다.

         implicit: function of command-line arguments
B        Binary digits as list
 S       Sum

여기에서 시도 하십시오 .


4

Pyth, 4 바이트

sjQ2

프로그램은 STDIN에서 해밍 무게를 찾을 수있는 숫자를 취합니다.


4

줄리아, 29 27 19 바이트

n->sum(digits(n,2))

단일 인수 인을 허용하는 익명 함수를 만듭니다 n. 그것을 사용하려면 f=n->...그것을 비슷한 것으로 할당 하고 좋아하십시오 f(1337).

이 digits()함수는 2 개의 인수와 함께 호출 될 때 주어진 밑의 입력 자릿수 배열을 반환합니다. 따라서 digits(n, 2)이진수를 반환합니다 n. 배열의 합을 취하면의 이진 표현에서 1의 수를 갖습니다 n.


이 훨씬 짧아 질 수 있습니다 줄리아 기능을 가지고count_ones
— 앤드류는 분석 재개 모니카 말한다

@AndrewPiliser : 제안 해 주셔서 감사합니다. 그러나 작업을 정확하게 수행하는 내장 함수는 표준 허점으로 간주되며 명시 적으로 허용되지 않는 경우 눈살을 찌푸립니다.
— Alex A.


3

Joe , 4 바이트

/+Ba

이것은 익명의 기능입니다. Ba숫자의 이진 표현을 제공하고 /+합산합니다.

   (/+Ba)13
3
   (/+Ba)500
6

3

R, 24 바이트

sum(intToBits(scan())>0)

scan() stdin에서 입력을 읽습니다.

intToBits()정수를 취하고 raw입력의 이진 표현 중 0과 1을 포함하는 유형의 벡터를 반환합니다 .

intToBits(scan())>0TRUE해당 이진 벡터 요소가 1 (모든 요소가 0 또는 1이고 1> 0이므로) 인 경우 각 요소가있는 논리 형 벡터를 반환합니다 FALSE.

R에서는 논리 벡터를 TRUE합하여 요소 수를 얻을 수 있으므로 위와 같이 논리 벡터를 합하면 원하는 것을 얻을 수 있습니다.

주 sum()처리 할 수없는 raw직접 입력을 사용 전에 논리를 따라서 대안.


sum(intToBits(scan()))동일 하지 않습니까?
— seequ

@Sieg : 불행히도 이후 sum()에 유형의 입력을 취할 수 없으므로 raw에서 반환 된 것 intToBits()입니다.
— Alex A.

정말 이상합니다.
— seequ

1
@Sieg : 그래, 나도 이상해. 오 잘 모든 돼지 고기가 완벽하다면 핫도그도 없을 것입니다.
— Alex A.

그리고 그것은 가장 이상한 은유입니다.
— seequ

3

루비, 18 바이트

n.to_s(2).count'1'


1
n.to_s(2).count ?1또한 작동하지만 길이는 동일합니다
— Piccolo

2019 년 버전 : n.digits (2) .sum / 15 바이트
— GB

3

넷째, 48 49 바이트

: c ?dup if dup 1- and recurse 1+ then ;
0 1337 c

실제 기능이 필요한 경우 두 번째 줄은

: c 0 swap c ;

"1337 c"라고 부릅니다. Forth의 비교적 장황한 제어 단어는 이것을 어렵게 만듭니다 (실제로, 이들을 많이 어렵게 만듭니다).

편집 : 이전 버전은 음수를 올바르게 처리하지 못했습니다.


3

매스 매 티카, 22 18 바이트

나에게 상기시켜 준 alephalpha에게 감사합니다 DigitCount.

DigitCount[#,2,1]&

감사 @alephalpha하지만 DigitCount 다른 매개 변수 : 소요
— 마틴 청산

3

ES6 (34 22 21 바이트) :

이것은 조금 더 단축 될 수있는 간단한 재귀 함수입니다. 단순히 조금 걸리고 다시 실행됩니다.

B=n=>n&&(1&n)+B(n>>1)

http://www.es6fiddle.net/imt5ilve/ 에서 시도 하십시오 (의 var이유가 필요합니다 'use strict';).

나는 내가 물고기를 이겼다는 것을 믿을 수 없다! !!

예전 것:

n=>n.toString(2).split(1).length-1

ES5 (39 바이트) :

두 기능 모두 ES5에 쉽게 적용 할 수 있습니다.

function B(n){return n?(1&n)+B(n>>1):0}

//ungolfed:

function B(number)
{
    if( number > 0 )
    {
        //arguments.callee points to the function itself
        return (number & 1) + arguments.callee( number >> 1 );
    }
    else
    {
        return 0;
    }
}

오래된 것:

function(n){return n.toString(2).split(1).length-1}

@ user1455003 은 나에게 가장 좋은 아이디어를 주었다.

function B(n,x){for(x=0;n;n>>=1)x+=n&1;return x}

ES6에 맞게 수정했으며 재귀를 많이 줄였습니다!


1
다음은 더 작은 'reguar'자바 스크립트 함수입니다. 함수 B (n, x) {for (x = 0; n; n >> = 1) x + = n & 1; return x}
— Wolfhammer

@ user1455003 많은 의견이나 제안을 부탁드립니다! 나는 그것을 사용하고 그것을 ES6에 적응시키고 많이 단축시켰다. 고맙습니다!
— Ismael Miguel

천만에요! 나는 당신이 한 일을 좋아합니다. 재귀와 함께 일반 자바 스크립트는 39로 줄어 듭니다! 기능 B (n) {return n? (1 & n) + B (n >> 1) : 0}
— Wolfhammer

@ user1455003 원하는 경우 ES5 부품을 편집하고 바이트 수를 골프 버전에 추가 할 수 있습니다. (나는 당신이 편집으로 명성을 얻는다고 생각합니다).
— Ismael Miguel

와우! 작동합니다 !!! 정말 고마워! 나는 이것이 더 짧아 질 수 있다는 것을 정말로 알고 있었다
— Ismael Miguel

2

> <> (물고기) , 24 바이트 + 2 = 26

0$11.>~n;
2,:?!^:2%:{+}-

프로그램은 단지 mod 2를 반복하고 입력 숫자가 0이 될 때까지 빼고 나눈 다음 mod 2의 합을 인쇄합니다.

-v예를 들어 플래그로 테스트

py -3 fish.py ones.fish -v 1337

16 비트 정수의 경우 코드 포인트 입력이 적절하지 않을 수 있습니다. ( -v플래그 버전은 여전히 ​​작동합니다.)
— randomra

@randomra 젠장, 네 말이 맞아. 유니 코드 입력은 작동하지만 16 비트는 범위를 벗어난 몇 자릿수에 불과합니다.
— Sp3000

2

PHP (38 바이트) :

이것은 ES6 답변 과 동일한 어프로치를 사용합니다.

<?=count(split(1,decbin($_GET[n])))-1;

이것은 전체 코드이므로 매개 변수를 사용하여 파일에 넣고 브라우저를 통해 액세스하면됩니다 n=<number>.

PHP <4.2 (32 바이트) :

조금 짧습니다.

<?=count(split(1,decbin($n)))-1;

지시어 register_globals는 Off기본적으로 PHP4.2에서 PHP5.4 (이때 제거)까지 설정 되었기 때문에 PHP <4.2에서만 안정적으로 작동합니다 .

로 php.ini파일 을 만들면 register_globals=On작동합니다.

코드를 사용하려면 POST 또는 GET을 사용하여 브라우저를 사용하여 파일에 액세스하십시오.

짤방 백업 봇 의 제안 (38/45 바이트) :

그는이 함수를 매우 흥미롭게 사용하는 2 가지 좋은 제안을했습니다. array_sum .

38 바이트 :

<?=array_sum(str_split(decbin(1337)));

45 바이트 :

<?=array_sum(preg_split('//', decbin(1337)));

이것은 정말 좋은 아이디어이며 36 바이트 길이로 조금 더 짧아 질 수 있습니다.

<?=array_sum(split(1,decbin(1337)));

2
또는 echo array_sum (str_split (decbin (1337)));을 사용할 수 있습니다. 너무 에코를 사용할 수 있습니다 array_sum (preg_split ( '//', decbin (1337)));
— Vinicius Monteiro

1
@ViniciusMonteiro 제안 해 주셔서 감사합니다. 나는 정말로 그것을 좋아했다! 답변에 추가했습니다.
— Ismael Miguel

<?=substr_count(decbin(1337),"1");(34 바이트)를 사용하여 4 바이트
— 얻기

1
@Cogicero 그리고 당신은 따옴표를 제거하여 더 많은 것을 저장할 수 있습니다 : <?=substr_count(decbin(1337),1);. 총 32 바이트입니다. 코드가 다른 코드라고 생각하면 자신의 답변으로 게시하고 싶지 않습니까? 나는 그것을 공감할 것이다!
— Ismael Miguel

@Cogicero 매개 변수를 사용하면 2 바이트 만 짧아집니다 <?=substr_count(decbin($argv[1]),1);(또는 $_GET[n]; 36 바이트)
— Titus


2

Japt, 3 바이트 (비경쟁)

¢¬x

여기에서 시도하십시오.


나는 어떤 이유로 든 그 날짜를 볼 수 없습니다.
— Mama Fun Roll

1
Haapt, Japt가 가장 짧습니다 : D BTW ¢o1 l도 잘 작동합니다. 또 다른 흥미로운 접근법은 -¢¬r-0; ¢¬이진수로 배열을 나누고 r-00부터 시작하여 빼기로 줄이며 -결과를 무시하여 양수로 만듭니다.
— ETHproductions

어제 밤부터 사용할 수 있습니다 ¢¬x.
— ETHproductions

2

밀랍 ,31 27 바이트

비경쟁 답변. 밀랍은이 도전보다 새로운 것입니다.

이 솔루션은 Brian Kherigan의 "Bit Twiddling Hacks"웹 사이트에서 세트 비트를 계산하는 방식을 사용합니다.

까지 루프를 실행하여 비트 수를 늘리고 number=number&(number-1)까지 반복합니다 number = 0. 이 솔루션은 비트 세트가있는 한 자주 루프를 통과합니다.

몇 가지 명령을 다시 정렬하여 4 바이트를 줄일 수 있습니다. 소스 코드와 설명이 모두 업데이트되었습니다.

pT_
>"p~0+M~p
d~0~@P@&<
{@<

설명:

pT_            generate IP, input Integer, redirect
>"             if top lstack value > 0 jump next instruction,
               otherwise continue at next instruction
  p            redirect if top lstack value=0 (see below)
   ~           flip top and 2nd lstack values
    0+         set top lstack value to 0, set top=top+2nd
      M        decrement top lstack value
       ~       flip top and 2nd lstack values
        p      redirect to lower left
        <      redirect to left
       &       top=top&2nd
      @        flip top and 3rd lstack values
    @P         increment top lstack value, flip top and 3rd values
 ~0~           flip top and 2nd values, set top=0, flip top and 2nd again
d              redirect to upper left
>"p~0+M.....   loop back

  p            if top lstack = 0 at " instruction (see above), redirect
  0            set lstack top to zero (irrelevant instruction)
  <            redirect to the left
 @             flip top and 3rd lstack values
{              output top lstack value as integer (bitcount)

밀랍 해석기, 언어 사양 및 예제가 포함 된 내 GitHub 저장소 를 복제하십시오 .


1

자바, 17 바이트

작동 byte, short, char,와 int. 람다로 사용하십시오.

Integer::bitCount

여기서 테스트

내장을 사용하지 않고 :

42 바이트

s->{int c=0;for(;s!=0;c++)s&=s-1;return c}

여기서 테스트


6
이것은 표준 허점입니다. 원하는 기능을 정확하게 수행하는 내장 함수는 금지되어 있습니다.
— FUZxxl

@FUZxxl OP는 절대 표준 허점을 금지하지 않습니다
— Cole Johnson


6
@FUZxxl es1024가 표준 허점을 기본적으로 닫는 것이 맞지만 내장 함수를 사용하는 것은 현재 + 43 / -26의 투표 분석에서 허점으로 허용되지 않습니다.
— 마틴 엔더

1

클립 , 6

두 가지 방법 :

cb2nx1

이것은 요구 사항을 간단하게 번역 한 것입니다 : 숫자의 밑이 2 인 표현의 수입니다.

r+`b2n

또 다른 방법은 밑이 2 인 숫자의 합을 취합니다.


1

옥타브, 18

sum(dec2bin(s)-48)

예:

octave:1> s=1337
s =  1337
octave:2> sum(dec2bin(s)-48)
ans =  6

1

GML (Game Maker Language), 21 바이트

for(n=0;x;n/=2)n+=x&1

1

C # 39 바이트

Convert.ToString(X,2).Count(C=>C=='1');


1

PowerShell (51 바이트)

"$([char[]][convert]::ToString($s,2)|%{"+$_"})"|iex

설명 :
[convert]::ToString($s,2)에서 이진 문자열 표현을 생성합니다 $s.
[char[]]그것을 char 배열로 캐스트하고 각 문자를 열거 할 수있게합니다.
|%{"+$_"}+ 기호가있는 각 문자 앞에 결과 하위 표현식을
"$()"내재적으로 호출 하여 파이프 된 문자열을 더합니다 (예 : "+1 +0 +1 +1 +0 +1 +0 +0"= 4)..ToString()
|iex


히야! 인라인 사용하지 왜,이 같은 논리에 따라 -join연산자와 암시가 .ToString()45 바이트를 달성하기 위해 [char[]][convert]::ToString($s,2)-join'+'|iex다른 접근 방식을 사용 인라인으로, ... 또는 -replace43 바이트를 달성하기 위해 운영자([convert]::ToString($s,2)-replace0).length
— AdmBorkBork

1

클로저, 42 바이트

#(count(filter #{\1}(Long/toString % 2)))

오른쪽에서 왼쪽으로 읽기, 이진 문자열로 변환, 일련의 문자로 변환, 필터링 1 s를 하고 얼마나 많은 수를 계산합니다.

편집을 할 지크의 도움으로


42 :#(count(filter #{\1}(Integer/toString% 2)))
— seequ

캐릭터가 하나 더 필요합니다#(count(filter #{\1}(Integer/toString % 2)))
— Neil Masson

아뇨 :)
— seequ

이것이 제가 시도했을 때 얻은 것입니다 :CompilerException java.lang.IllegalArgumentException: No matching method: toString_PERCENT_
— Neil Masson

Try Clojure에서 테스트했습니다. 페이지가 갑자기 인식되지 않는 것 같습니다 Integer/toString. 그것은 두 번째 전에 일했습니다.
— seequ

1

하스켈 42 자

t 0=[]
t n=t(quot n 2)++[rem n 2]
f=sum.t

함수를 선언 f :: Integer -> Integer
대화식 인터프리터에서 사용을f <number> 하거나 main=print$f <number>파일 끝에 행 을 추가 합니다.


당신은 직접 합산하여 바이트을 많이 절약 할 수 있습니다 rem n 2들 대신에 그것의 목록을 구축하고 사용하지으로 div대신 quot: t 0=0 t n=t(div n 2)+rem n 2더 - f이상.
— nimi

1

Matlab, 13 바이트

de2bi이진수를 나타내는 0과 1로 구성된 벡터를 만들고 sum모든 항목의 합계를 반환합니다.

sum(de2bi(n))

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