Policz liczbę jedynek w 16-bitowej liczbie całkowitej bez znaku

24

Napisz kilka instrukcji, które będą liczyć liczbę jedności w szesnastobitowej liczbie całkowitej bez znaku.

Na przykład, jeśli dane wejściowe są 1337, to wynik jest taki, 6że 1337jako szesnastobitowa liczba binarna 0000010100111001zawiera sześć.

ayane
źródło
2
Wskazówka: podobnie jak niektóre cyfry w liczbie odpowiadają
cyfrze
8
@PyRulez Dowolna liczba wynosi zero modulo 1.
Thomas
1
Cześć, wybrałeś złą odpowiedź jako zaakceptowaną (domyślnie logika przerywnika remisu dla najwcześniejszego postu).
Optymalizator
4
@ Thomas nigdy nie powiedziałem, że to przydatna wskazówka.
PyRulez
2
Dlaczego to pytanie przyciąga bliskie głosy PO opublikowaniu większości odpowiedzi? Zamknij wyborców, podaj swój powód w komentarzach. Jeśli jest to akceptacja 4-bajtowej odpowiedzi es1024 (bardzo sprytnej), która nie jest zgodna ze standardowymi lukami (ponieważ używa wbudowanego), proszę podać, że jest to powód. W przeciwnym razie co to jest?
Level River St

Odpowiedzi:

37

80386 Kod maszynowy, 4 bajty

F3 0F B8 C1

który przyjmuje liczbę całkowitą cxi wyprowadza licznik ax, i jest równoważny z:

popcnt ax, cx     ; F3 0F B8 C1

I tu jest 11 10 rozwiązanie bajt nie używając POPCNT:

31 C0 D1 E9 10 E0 85 C9 75 F8

co jest równoważne z:

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
es1024
źródło
Czy jest to tryb 32-bitowy lub 16-bitowy (rzeczywisty lub chroniony)?
FUZxxl,
2
@FUZxxl Zespół przewidziane jest 16-bitowym, ale zastępując axi cxz eax, a ecxzmienia go do 32-bitowych. Kod bajtowy jest taki sam dla obu.
es1024
1
@ es1024 Kod bajtowy jest taki sam, jeśli został skompilowany w trybie 16-bitowym, a wersja 32-bitowa w trybie 32-bitowym.
Cole Johnson
2
Czy popcnt nie jest wbudowany, a zatem nie spełnia standardowych luk? Nadal zasługa za drugie rozwiązanie.
Alchymist
5
Kiedy podajesz długość kodu maszynowego , czy tytuł nie powinien być „80386 Kodem maszynowym”, a nie „80386 Asembler”?
Kevin Reid
14

Python 2, 17 bajtów

bin(s).count('1')

binWbudowaną Zwraca całkowitą konwertowane na ciąg binarny. Następnie zliczamy 1cyfry:

>>> s=1337
>>> bin(s)
'0b10100111001'
>>> bin(s).count('1')
6
Logic Knight
źródło
11

J (5 znaków)

J nie ma jawnych typów. To robi właściwą rzecz dla wszystkich liczb całkowitych.

+/@#:
  • +/ Suma
  • @ z
  • #: podstawowa reprezentacja dwóch
FUZxxl
źródło
11

C, 21

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

powiedziałeś „napisz kilka instrukcji” (a nie „funkcję”), więc założyłem, że liczba jest podana, xa liczba 1 jest zwrócona n. Jeśli nie muszę inicjować n, mogę zapisać 3 bajty.

Jest to adaptacja słynnego wyrażenia x&x-1do testowania, czy coś ma potęgę 2 (fałsz, jeśli tak, prawda, jeśli nie jest).

Tutaj działa on pod numerem 1337 z pytania. Zauważ, że odjęcie 1 odwraca najmniej znaczący 1 bit i wszystkie zera w prawo.

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

EDYCJA: dla kompletności, oto naiwny algorytm, który jest o jeden bajt dłuższy (i nieco wolniejszy).

for(n=0;x;x/=2)n+=x&1;
Level River St
źródło
1
@ edc65, jak się okazuje, wynalazłem koło na nowo. Przynajmniej zapisałem 2 bajty, pomijając {}. To takie proste zadanie, że nie powinienem się dziwić, że ktoś już to wymyślił.
Level River St
„Po raz pierwszy opublikowany w 1960 roku” , imponujący.
mbomb007
Korekta do naiwnego algorytmu:for(n=0;x;x/=2)n+=x&1;
Helios
1
@ nmxprime OP prosi o niepodpisane int. dla -7 = 11111111 11111111 11111111 11111001 na moim 32-bitowym kompilatorze dostaję 30 za szybki algorytm, co jest poprawne. W przypadku naiwnego algorytmu iteruje on przez -7, -7 / 2 = -3, -3 / 2 = -1, -1 / 2 = 0. To daje niepoprawną odpowiedź. Zmiana x / = 2 na x >> = 1 może dać poprawną odpowiedź w niektórych kompilatorach, ale C nie jest określone, czy 1 lub 0 jest przesunięte do pustego bitu dla >> na liczbach ujemnych. Te kompilatory, które przesuwają 1 w, przejdą w nieskończoną pętlę. Obejściem tego problemu jest zdefiniowanie x jako int bez znaku. Następnie x = -7 ładuje (1 << 32) -7 = 4294967289 na x.
Level River St
5

Galaretka , niekonkurująca

Ta odpowiedź nie jest konkurencyjna, ponieważ język został utworzony po opublikowaniu wyzwania.

2 bajty:

BS

Jelly to nowy język napisany przez @Dennis, o składni podobnej do J.

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

Wypróbuj tutaj .

lirtosiast
źródło
4

Pyth, 4 bajty

sjQ2

Program przyjmuje numer, którego ciężar wbijający można znaleźć na STDIN.

isaacg
źródło
4

Julia, 29 27 19 bajtów

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

Stwarza anonimową funkcję, która przyjmuje jeden argument, n. Aby go użyć, przypisz go do czegoś podobnego f=n->...i nazwij tak f(1337).

digits()Funkcje, po wywołaniu z 2 argumentów zwraca tablicę cyfr wejścia w danej podstawy. digits(n, 2)Zwraca więc cyfry binarne z n. Weź sumę tablicy, a będziesz miał ich liczbę w reprezentacji binarnej n.

Alex A.
źródło
Może to być znacznie krótsze: Julia ma funkcjęcount_ones
Andrew mówi Przywróć Monikę
@AndrewPiliser: Dzięki za sugestię, ale wbudowane funkcje, które dokładnie wykonują to zadanie, są uważane za standardową lukę i są niezadowolone, gdy nie są wyraźnie zabronione.
Alex A.,
3

CJam, 6 bajtów

ri2b:+

ri         "Read the input and convert it to integer";
  2b       "Convert the integer into base 2 format";
    :+     "Sum the digits of base 2 form";

Wypróbuj online tutaj

Optymalizator
źródło
3

Joe , 4 bajty

/+Ba

To anonimowa funkcja. Bapodaje binarną reprezentację liczby i /+sumuje ją.

   (/+Ba)13
3
   (/+Ba)500
6
patrz
źródło
3

R, 24 bajty

sum(intToBits(scan())>0)

scan() odczytuje wejście ze standardowego wejścia.

intToBits() przyjmuje liczbę całkowitą i zwraca wektor typu raw zawierający zera i jedynki reprezentacji binarnej wejścia.

intToBits(scan())>0 zwraca logiczny wektor, w którym znajduje się każdy element TRUE jeśli odpowiadający mu element binarny to 1 (ponieważ wszystkie elementy mają wartość 0 lub 1 i 1> 0), w przeciwnym razie FALSE.

W R można zsumować wektor logiczny, aby uzyskać liczbę TRUEelementów, więc sumowanie wektora logicznego jak wyżej daje nam to, czego chcemy.

Zauważ, że sum()nie można rawbezpośrednio obsługiwać danych wejściowych, dlatego obejście za pomocą logiki.

Alex A.
źródło
Nie sum(intToBits(scan()))byłoby tak samo?
patrz
@Sieg: Niestety nie, ponieważ sum()nie można pobrać typu raw, który jest zwracany intToBits().
Alex A.,
To jest dla mnie naprawdę dziwne.
patrz
1
@Sieg: Tak, to też jest dla mnie dziwne. No cóż. Gdyby każdy wieprzowina był doskonały, nie mielibyśmy hot dogów.
Alex A.,
I to jest najdziwniejsza metafora w historii.
patrz
3

Rubinowy, 18 bajtów

n.to_s(2).count'1'

GreyCat
źródło
1
n.to_s(2).count ?1również działa, ale ma tę samą długość
Piccolo
Wersja 2019: n.digits (2) .sum / 15 bytes
GB
3

Dalej, 48 49 bajtów

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

Jeśli potrzebna jest rzeczywista funkcja, to pojawia się druga linia

: c 0 swap c ;

i nazywacie to „1337 c”. Stosunkowo szczegółowe słowa kontrolne Fortha sprawiają, że jest to trudne (w rzeczywistości sprawia, że ​​wiele z nich jest trudnych).

Edycja: Moja poprzednia wersja nie obsługiwała poprawnie liczb ujemnych.

Nagora
źródło
3

Mathematica, 22 18 bajtów

Dzięki alephalpha za przypomnienie DigitCount.

DigitCount[#,2,1]&
Martin Ender
źródło
@alephalpha dzięki, ale DigitCount przyjmuje inny parametr :)
Martin Ender
3

ES6 (34 22 21 bajtów):

Jest to prosta funkcja rekurencyjna, którą można nieco skrócić. To po prostu zajmuje trochę czasu i uruchamia się ponownie:

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

Wypróbuj na http://www.es6fiddle.net/imt5ilve/ (potrzebujesz varpowodu 'use strict';).

Nie mogę uwierzyć, że pokonałem Fisha !!!

Ten stary:

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

ES5 (39 bajtów):

Obie funkcje można łatwo dostosować do 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;
    }
}

Stary:

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

@ user1455003 dał mi naprawdę świetny pomysł, który „uruchomił” najmniejszy:

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

Dostosowałem go do ES6 i sprawiłem, że rekurencyjne jest znaczne skracanie!

Ismael Miguel
źródło
1
Oto mniejsza funkcja javascript „reguar”. funkcja B (n, x) {for (x = 0; n; n >> = 1) x + = n & 1; return x}
wolfhammer
@ user1455003 Dziękuję DUŻO lub twoją sugestię! Użyłem go i dostosowałem do ES6 i znacznie skróciłem. Dziękuję Ci!
Ismael Miguel
Proszę bardzo! Podoba mi się to, co z tym zrobiłeś. Z rekurencją zwykły javascript spada do 39! funkcja B (n) {return n? (1 & n) + B (n >> 1): 0}
wolfhammer
@ user1455003 Jeśli chcesz, możesz edytować część ES5 i dodać liczbę bajtów do wersji golfowej. (Myślę, że zyskujesz reputację dzięki edycjom).
Ismael Miguel
@ user81655 WOW! To działa!!! Dziękuję bardzo! Naprawdę wiedziałem, że można to skrócić
Ismael Miguel,
2

> <> (Ryba) , 24 bajty + 2 = 26

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

Program po prostu wykonuje powtarzany mod 2, odejmuje i dzieli, aż liczba wejściowa osiągnie zero, a następnie drukuje sumę mod 2s.

Testuj z -vflagą, np

py -3 fish.py ones.fish -v 1337
Sp3000
źródło
Dla 16-bitowej liczby całkowitej wejście kodowe prawdopodobnie nie jest odpowiednie. (Wersja -vflagowa nadal działa.)
randomra
@randomra Damn, masz rację. Podczas gdy wejście Unicode działa, 16-bit to tylko kilka rzędów wielkości poza zakresem ...
Sp3000,
2

PHP (38 bajtów):

Używa tego samego podejścia, co moja odpowiedź ES6

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

Jest to pełny kod, wystarczy umieścić go w pliku i uzyskać do niego dostęp w przeglądarce za pomocą parametru n=<number>.

PHP <4.2 (32 bajty):

To jest trochę krótsze:

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

Działa to niezawodnie tylko w PHP <4.2, ponieważ dyrektywa register_globalszostała Offdomyślnie ustawiona od PHP4.2 do PHP5.4 (do tego czasu została usunięta).

Jeśli utworzysz php.iniplik za pomocą register_globals=On, to zadziała.

Aby użyć kodu, uzyskaj dostęp do pliku za pomocą przeglądarki, używając POST lub GET.

@ViniciusMonteiro 's sugestie (38/45 bytes):

Podał 2 naprawdę dobre sugestie, które mają bardzo ciekawe zastosowanie tej funkcji array_sum:

38 bajtów:

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

45 bajtów:

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

To naprawdę świetny pomysł i można go nieco skrócić, aby miał 36 bajtów:

<?=array_sum(split(1,decbin(1337)));
Ismael Miguel
źródło
2
Lub możesz użyć echa array_sum (str_split (decbin (1337))); i możesz użyć zbyt echa array_sum (preg_split ('//', decbin (1337)));
Vinicius Monteiro
1
@ ViniciusMonteiro Bardzo dziękuję za sugestię. Naprawdę mi się podobało! Dodałem to do odpowiedzi.
Ismael Miguel
Zyskaj cztery bajty, używając <?=substr_count(decbin(1337),"1");(34 bajty)
Cogicero
1
@Cogicero I można zaoszczędzić jeszcze więcej poprzez usunięcie cytatów: <?=substr_count(decbin(1337),1);. To w sumie 32 bajty. Biorąc pod uwagę, że jest to wystarczająco inny kod, czy nie chcesz go opublikować jako własnej odpowiedzi? Na pewno będę go głosować!
Ismael Miguel
@Cogicero To tylko dwa bajty krótsze, jeśli używasz parametryzacji: <?=substr_count(decbin($argv[1]),1);(lub $_GET[n]; 36 bajtów)
Titus
2

Japt, 3 bajty (niekonkurencyjny)

¢¬x

Wypróbuj tutaj.

Mama Fun Roll
źródło
Człowieku, nigdy nie widzę tych dat z jakiegoś powodu.
Mama Fun Roll
1
Haha, Japt jest najkrótszy: D BTW, też ¢o1 lby działał. Innym interesującym podejściem jest -¢¬r-0; ¢¬dzieli się na tablicę cyfr binarnych, r-0zmniejsza odejmując, zaczynając od 0, i -neguje wynik, czyniąc go dodatnim.
ETHproductions
Od ostatniej nocy możesz teraz używać ¢¬x.
ETHproductions
2

wosk pszczeli ,31 27 bajtów

Odpowiedź niekonkurencyjna. Wosk pszczeli jest nowszy niż to wyzwanie.

W tym rozwiązaniu Brian Kherigan zlicza zestawy bitów ze strony internetowej „Bit Twiddling Hacks”.

po prostu przebiega przez pętlę, zwiększając liczbę bitów, i iterując number=number&(number-1)aż do number = 0. Rozwiązanie przechodzi przez pętlę tylko tak często, jak jest ustawionych bitów.

Mógłbym ogolić 4 bajty, zmieniając kilka instrukcji. Zaktualizowano kod źródłowy i objaśnienie:

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

Wyjaśnienie:

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)

Sklonuj moje repozytorium GitHub zawierające interpreter wosku pszczelego, specyfikację języka i przykłady.

ML
źródło
1

Java, 17 bajtów

Działa na byte, short, char, i int. Użyj jako lambda.

Integer::bitCount

Przetestuj tutaj

Bez użycia wbudowanych:

42 bajty

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

Przetestuj tutaj

Numer jeden
źródło
6
jest to standardowa luka: wbudowane funkcje, które robią dokładnie to, co chcesz, są zabronione.
FUZxxl,
@FUZxxl OP nigdy nie zakazał standardowych luk
Cole Johnson
6
@FUZxxl Podczas gdy es1024 ma rację, że standardowe luki są domyślnie zamknięte, używanie wbudowanych funkcji nie jest obecnie akceptowaną luką przy rozbiciu głosów na + 43 / -26.
Martin Ender
1

Klip , 6

2 drogi:

cb2nx1

Jest to proste tłumaczenie tego wymogu: liczba jedynek w reprezentacji liczby podstawowej 2.

r+`b2n

Inna metoda, która przyjmuje sumę cyfr reprezentacji base-2.

Ypnypn
źródło
1

Oktawa, 18 lat

sum(dec2bin(s)-48)

Przykład:

octave:1> s=1337
s =  1337
octave:2> sum(dec2bin(s)-48)
ans =  6
alephalpha
źródło
1

GML (Game Maker Language), 21 bajtów

for(n=0;x;n/=2)n+=x&1
Timtech
źródło
1

C # 39 bajtów

Convert.ToString(X,2).Count(C=>C=='1');
Sbecker
źródło
1

Perl, 21

$r=grep$v&1<<$_,0..15
nutki
źródło
1

PowerShell (51 bajtów)

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

Objaśnienie:
[convert]::ToString($s,2)tworzy binarną reprezentację ciągu znaków z $s.
[char[]]rzuca go jako tablicę znaków i pozwala nam wyliczyć każdy znak.
|%{"+$_"}poprzedza każdy znak znakiem +
"$()"niejawnie wywołuje .ToString()wynikowe wyrażenie podrzędne
|iexsumuje potokowy ciąg znaków (tj. „+1 +0 +1 +1 +0 +1 +0 +0” = 4)

Mathias R. Jessen
źródło
Cześć! Postępując zgodnie z tą samą logiką, dlaczego nie użyć -joinoperatora wbudowanego i niejawnego, .ToString()aby osiągnąć 45 bajtów z [char[]][convert]::ToString($s,2)-join'+'|iex... LUB, jako inne podejście użyć -replaceoperatora wbudowanego , aby uzyskać 43 bajty z([convert]::ToString($s,2)-replace0).length
AdmBorkBork
1

Clojure, 42 bajty

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

Czytanie od prawej do lewej, konwersja na ciąg binarny, konwersja na ciąg znaków, filtrowanie 1 si i liczenie, ile masz.

EDYCJA Z pomocą Sieg

Neil Masson
źródło
42:#(count(filter #{\1}(Integer/toString% 2)))
patrz
Potrzebujesz jeszcze jednej postaci#(count(filter #{\1}(Integer/toString % 2)))
Neila Massona,
Nie ty nie. :)
patrz
Oto, co dostałem, gdy spróbowałem:CompilerException java.lang.IllegalArgumentException: No matching method: toString_PERCENT_
Neil Masson,
Przetestowałem to w Try Clojure. Najwyraźniej strona nagle nie rozpoznaje Integer/toString. Ale działało to sekundę temu.
patrz
1

Haskell 42 znaki

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

deklaruje f :: Integer -> Integer
użycie funkcji z interaktywnego interpretera jako f <number>lub dodaje linię main=print$f <number>na końcu pliku.

HEGX64
źródło
Możesz zaoszczędzić wiele bajtów, bezpośrednio sumując je rem n 2zamiast budując ich listę i używając divzamiast quot: t 0=0 t n=t(div n 2)+rem n 2- fjuż nie .
nimi
1

Matlab, 13 bajtów

de2bitworzy wektor zer i jedynek reprezentujących liczbę binarną, i sumpo prostu zwraca sumę wszystkich wpisów.

sum(de2bi(n))
wada
źródło
1

𝔼𝕊𝕄𝕚𝕟, 4 znaki / 11 bajtów (niekonkurencyjne)

⨭⟦ïⓑ

Try it here (Firefox only).

Wyjaśnienie

Konwertuje dane wejściowe na binarne, dzieli wzdłuż znaków i otrzymuje sumę wynikowej tablicy.

Mama Fun Roll
źródło