부호없는 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 비트위한 axcx함께 eaxecx32 비트를 변경한다. 바이트 코드도 동일합니다.
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_globalsOff기본적으로 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.