Gibt die Anzahl der Einsen in einer Binärzahl ohne Verwendung von bitweisen Operatoren aus


14

Beschreibung

Gib bei gegebener Zahl die Anzahl der 1s in binärer Darstellung aus.

Eingang

Eine Zahl >= 0in Basis 10, die die höchste Zahl, die Ihre Sprache verarbeiten kann, nicht überschreitet.

Ausgabe

Der Betrag von 1s in binärer Darstellung.

Gewinnbedingung

Der kürzeste Code gewinnt.

Nicht erlaubt

  • Bitweise Operatoren. Andere Operatoren wie Addition und Multiplikation sind zulässig.
  • Eingebaute Basisumwandlungsfunktionen.

Beispiele

Input:     Ouput:

56432      8


Input:     Output:

45781254   11


Input:     Output:

0          0

Sind Funktionen erlaubt? Ich möchte eine Java-Lösung machen, aber das Schreiben von vollständigem Code ist zu mühsam ...: /
HyperNeutrino

1
Ich nehme an, ich werde Wise nicht für diese Herausforderung verwenden ... :)
MildlyMilquetoast

Antworten:


16

APL, 9 12 Zeichen

+/2|⌊⎕÷2*⍳32

Dies setzt voraus, dass der Interpreter 32-Bit-Ganzzahlen verwendet und diese ⎕IOauf 0 gesetzt sind (was bedeutet, dass monadisch mit 0 anstatt mit 1 beginnt). Ich habe die 32-Bit-Version von Dyalog APL verwendet .

Erklärung von rechts nach links:

  • ⍳32erzeugt einen Vektor der ersten 32ganzen Zahlen (da ⎕IO0 ist, beginnt dieser Vektor mit 0).
  • *ist die Potenzfunktion. In diesem Fall generiert 2es die Potenz jedes Elements des Vektors, der als rechtes Argument angegeben wird.
  • ÷ist die Division durch Funktion. Es gibt uns (ausgewertete Benutzereingaben) geteilt durch jedes Element des Vektors zu seiner Rechten (jede Zweierpotenz).
  • Fußböden jedes Element des Arguments auf der rechten Seite.
  • 2|gibt uns den Rest jedes Elements von zu seiner Rechten geteilt durch 2.
  • /reduziert (faltet) sein rechtes Argument mit der Funktion nach links +,.

Nicht mehr ganz 9 Zeichen. :(

Alte, regelwidrige Version:

+/⎕⊤⍨32/2

Erklärung von rechts nach links:

  • 32/2: Replizieren 2, 32mal.
  • pendelt die dyadische Funktion nach links, was in diesem Fall (dh X⊤⍨Yäquivalent zu Y⊤X) ist.
  • ist die Codierungsfunktion. Es codiert die Ganzzahl rechts in der Basis links davon. Beachten Sie, dass aufgrund des Pendeloperators das rechte und das linke Argument vertauscht werden. Die Basis wird daher für die Anzahl der erforderlichen Stellen wiederholt 32/2.
  • ist eine niladische Funktion, die Benutzereingaben akzeptiert und auswertet.
  • +/reduziert (faltet) sein rechtes Argument mit +. (Wir addieren die Nullen und Einsen.)

2
Bricht das nicht die Built-in base conversion functionsKontraktion?
Gareth

Hoppla! Habe das verpasst.
Dillon Cower

Gah! Dachte, ich hätte mir mit meinem J-Programm eine Chance zum Kämpfen gegeben! :-) Gut gemacht.
Gareth

@Gareth: Ich habe es erst bemerkt, als ich deine Erklärung gelesen habe, aber meine Antwort ist ziemlich identisch mit deiner! Ich denke, das kann man von APL und J. erwarten. :)
Dillon Cower

11

Brainbool , 2

,.

Die vernünftigste Interpretation, meiner Meinung nach (und was den meisten Antworten verwenden) von „höchster Zahl Ihrer Sprache ist in der Lage zu handhaben “ ist „größte Zahl Ihrer Sprache nativ unterstützt“. Brainbool ist ein Brainfuck-Derivat, das Bits anstelle von Bytes verwendet und Eingaben und Ausgaben in Binärform ( 0und 1Zeichen) anstelle von Zeichencodes vornimmt. Die größte nativ unterstützt Zahl ist daher 1, und die kleinste ist 0, die Hamming - Gewichte haben 1und 0jeweils.

Brainbool wurde laut Esolang im Jahr 2010 gegründet.


9
Ich wusste, dass es das gegeben haben musste, aber ich brauchte eine Stunde, um die Brainfuck-Derivate auf Esolang zu durchsuchen und Brainbool zu finden.
Lirtosiast

8

J, 13 Zeichen

(+ die Anzahl der Ziffern in der Nummer)

+/2|<.n%2^i.32

Verbrauch: ersetzen Sie das n im Programm durch die zu testende Nummer.

Beispiele:

+/2|<.56432%2^i.32
8
+/2|<.45781254%2^i.32
11
+/2|<.0%2^i.32
0

Es gibt wahrscheinlich eine Möglichkeit, dies neu zu ordnen, damit die Nummer am Anfang oder Ende platziert werden kann, aber dies ist mein erster J-Eintrag und mein Kopf tut jetzt leicht weh.

Erläuterung (hauptsächlich, damit ich es in Zukunft verstehe)

i.32 - Erstellt ein Array mit den Zahlen 1 bis 32

2^ - verwandelt die Liste in Zweierpotenzen 1 bis 4294967296

n% - teilt die eingegebene Nummer durch jedes Element in der Liste

<. - rundet alle Divisionsergebnisse auf die nächste Ganzzahl ab

2|- wie %2in den meisten Sprachen - liefert 0 wenn gerade und 1 wenn ungerade

+/ - summiert die Elemente in der Liste (die jetzt nur 1s oder 0s sind)


Ich freue mich, dies zu verbessern, sobald es von stdin (oder was auch immer J hat) liest.
Steven Rumbalski

Das Beste, was ich tun kann (vielleicht, je nachdem, wie), ist die Eingabe an das Ende des Programms zu verschieben. Standardeingabe wird in der Frage jedoch nicht erwähnt?
Gareth

Es tut mir leid, dass ich die Art der Eingabe nicht angegeben habe. Es wäre unfair, die Regeln jetzt zu ändern, also akzeptiere ich diese. Ich werde es beim nächsten Mal erwähnen!
pimvdb

@pimvdb Kein Problem, es war keine Beschwerde. Ich denke, mit J-Programmen können Sie nur ein Verb definieren, das auf die angegebene Eingabe angewendet wird. Ich bin mir nicht sicher, wie ich das ändern soll, um das zu tun. Vielleicht könnte mir JB oder einer der anderen J-Experten dabei helfen ...
Gareth

... und nachdem ich mehr gelesen habe, sehe ich jetzt, dass ich mich bei der Standardeingabe völlig geirrt habe.
Gareth

8

Brainfuck, 53 Zeichen

Diesem fehlte eine obligatorische Brainfuck-Lösung, daher habe ich diese erstellt:

[[->+<[->->>>+<<]>[->>>>+<<]<<<]>>>>[-<<<<+>>>>]<<<<]

Übernimmt die Nummer aus Zelle 1 und fügt das Ergebnis in Zelle 6 ein.

Nicht registrierte und kommentierte Version:

[  while n != 0
  [  div 2 loop
    -
    >+<  marker for if/else
    [->->>>+<<]  if n != 0 inc n/2
    >
    [->>>>+<<]  else inc m
    <<<
  ]
  >>>>  move n/2 back to n
  [-<<<<+>>>>]
  <<<<
]

6

Python 2.6, 41 Zeichen

t,n=0,input()
while n:t+=n%2;n/=2
print t

Anmerkung: Meine andere Antwort verwendet Lambda und Rekursion und diese verwendet eine while-Schleife. Ich denke, sie sind unterschiedlich genug, um zwei Antworten zu rechtfertigen.


6

Ruby, 38 Zeichen

f=->u{u<1?0:u%2+f[u/2]}
p f[gets.to_i]

Eine andere Lösung mit Ruby und dem gleichen rekursiven Ansatz wie Steven.


5

GolfScript, 17 16 Zeichen

~{.2%\2/.}do]0-,

Bearbeiten: Neue Version speichert 1 Zeichen, indem Listenoperation anstelle von Falz verwendet wird (ursprüngliche Version war ~{.2%\2/.}do]{+}*, direkte Zählversion:) ~0\{.2%@+\2/.}do;.


5

C 45

f(n,c){for(c=0;n;n/=2)c+=n%2;printf("%d",c);}

Hier ist nichts Besonderes für das Golfen in C: impliziter Rückgabetyp, impliziter ganzzahliger Typ für Parameter.


4

Python 2.6, 45 Zeichen

b=lambda n:n and n%2+b(n/2) 
print b(input())

1
Kann durch Verwendung defeines Lambdas um zwei Zeichen gekürzt werden .
Konrad Rudolph

1
@KonradRudolph: Tatsächlich verlieren Sie den Vorteil, sobald Sie die return-Anweisung einfügen.
Steven Rumbalski

Ups, das habe ich vergessen. Blöd.
Konrad Rudolph

Das brauchst du nicht print b(input()). Es ist akzeptabel, den Wert zurückzugeben und "input" als Argumente für Funktionen zu verwenden.
Caird Coinheringaahing

4

Perl, 45 43 36 Zeichen

$n=<>;while($n){$_+=$n%2;$n/=2}print

Vielen Dank an Howard für 45-> 43 und an User606723 für 43-> 36.


Sie könnten $n=int($n/2)die 2 kürzeren Zeichen verwenden.
Howard

Sind wir sicher, dass wir die int () brauchen? $n=<>;while($n){$_+=$n%2;$n/=2}printDies wird so lange wiederholt, bis $ n / 2 endlich nahe genug bei 0 angelangt ist, aber kümmert es uns? ;)
user606723 30.12.11

@ user606723 Ich habe das gerade ausprobiert und es scheint perfekt zu funktionieren, zumindest für jeden Fall bis zu 1000.
PhiNotPi

3

Perl, 30 Zeichen

$==<>;1while$_+=$=%2,$=/=2;say

Basierend auf der PhiNotPi-Lösung , mit etwas mehr Golf. Führen Sie mit aus perl -M5.010, um die Perl 5.10- sayFunktion zu aktivieren .


Tut die $=spezielle Variable etwas Besonderes in Ihrem Programm oder ist es nur eine gewöhnliche Variable?
PhiNotPi

2
@PhiNotPi: Nimmt $=nur ganzzahlige Werte an int.
Ilmari Karonen

Sollte das Befehlszeilenargument nicht Teil der Zeichenanzahl sein?
Soham Chowdhury

@SohamChowdhury: Nicht für diesen Meta-Thread .
Ilmari Karonen

3

Common Lisp, 12 Zeichen

(unter der Annahme eines 1-Zeichen-Variablennamens - dh: 11 + Nummernlänge)

Es ist keine Basiskonvertierungsfunktion, daher sollte es funktionieren:

(logcount x)

Beispiele:

[1]> (logcount 0)
0
[2]> (logcount 1)
1
[3]> (logcount 1024)
1
[4]> (logcount 1023)
10
[5]> (logcount 1234567890123456789012345678901234567890)
68

(Mit GNU CLISP.)


Hm na ja, nicht genau das, was ich als Antwort sehen wollte :) Ich glaube nicht, dass ich das akzeptieren kann. Es ist im Grunde nur ein weiterer Fall von diesem .
pimvdb

3

C 61 60 57 53 Zeichen

void f(x){int i=0;for(;x;x/=2)i+=x%2;printf("%u",i);}

Der Funktionskörper ist nur 38 Zeichen. Bearbeiten : Bitweiser Operator entfernt Bearbeiten : printfAus der Schleife entfernen, wie in den Kommentaren vorgeschlagen Bearbeiten : Zur K & R-Deklaration wechseln; Auch dies ist nicht mehr C99-spezifisch


Ich sehe bitweise !!!
Joanis

Es tut mir leid, aber der AND-Operator zählt auch als bitweiser Operator.
Pimvdb

@ M.Joanis: duh, danke fürs mitbekommen. Fest.
Sam Hocevar

1
Ich denke, Sie könnten ein paar Zeichen sparen, wenn Sie zu K & R C wechseln. Wenn Sie damit einverstanden sind.
JB

Sie können dies um vier Zeichen verkürzen, indem Sie den Ausdruck aus der Schleife herausziehen.
marinus

3

Gleichstrom - 26 Zeichen

Dies ist ziemlich lang, hauptsächlich wegen des Fehlens von Schleifenkonstrukten in dc.

0?[d2%rsi+li2/d0<x]dsxx+p

Addiert das Modulo 2 der Zahl und dividiert die Zahl durch bis, bis sie Null erreicht. Kann mit beliebig langen ganzen Zahlen umgehen.

Beispiel:

$ dc -e '0?[d2%rsi+li2/d0<x]dsxx+p' <<< 127
7
$ dc countones.dc <<< 1273434547453452352342346734573465732856238472384263456458235374653784538469120235
138

3

C, 66 Zeichen

main(int n,char **a){printf("%u",__builtin_popcount(atoi(a[1])))};

Hinweis: Erfordert gcc oder gcc-kompatiblen Compiler (zB ICC, Clang).

__builtin_popcountKompiliert für einige CPUs zu einer einzigen Anweisung (zB POPCNTauf x86).


Ist es richtig, dass __builtin_popcounttatsächlich nur das Zählen von 1s selbst implementiert wird ? Wenn ja, obwohl es nicht streng nach den Regeln falsch ist, halte ich das ehrlich gesagt nicht für einen fairen Einstieg.
pimvdb

Sie sollten dies wahrscheinlich in der Frage festlegen, wenn Sie keine Einträge zulassen möchten, die die integrierten Funktionen einer bestimmten Sprache oder eines bestimmten Compilers nutzen.
Paul R

Dies ist kein legales C ++, da Sie in C ++ den Rückgabetyp für main nicht weglassen oder printfohne vorheriges Include verwenden können.
Celtschk

@celtschk: fair point - herausgearbeitetC++
Paul R

2

JavaScript, 78 72 71 Zeichen

Ich werde meine ursprüngliche Lösung posten, die ich mir ausgedacht habe, bevor ich auch die Frage stelle. Es gibt aber schon eine viel bessere JavaScript-Antwort :)

for(n=prompt(a=0),j=1;j<=n;j*=2)for(i=j;i<=n;i+=2*j)n<i+j&&a++;alert(a)

http://jsfiddle.net/Mk8zd/1/

Die Idee kommt von bestimmten "Gedankenlesekarten", die es Ihnen ermöglichen, die Nummer zu ermitteln, die jemand anderes im Sinn hat, indem Sie ihm Karten zeigen und sagen lassen, auf welchen Karten seine Nummer ersichtlich ist.

Es funktioniert, weil jede Zahl eine eindeutige Kombination von 1s / 0s in der Binärdatei ist. Meine Lösung überprüft, auf welchen "Karten" die Nummer ersichtlich ist, um festzustellen, wie viele1 s sie hat. Es ist nur nicht sehr effizient, obwohl ...

ich fand dieses Dokument gefunden, das die Gedankenlesetechnik beschreibt.


2

Haskell (60 Zeichen)

f n=sum[1|x<-[0..n],odd$n`div`2^x]
main=interact$show.f.read

2

PHP, 57

$i=$s=0;for(;$i<log($n,2);){$s+=$n/pow(2,$i++)%2;}echo$s;

Dies setzt voraus, dass $n der zu testende Wert enthalten ist.

PHP, 55 (alternative Lösung)

function b($i){return$i|0?($i%2)+b($i/2):0;}echo b($n);

Dies setzt wiederum voraus, dass $nder zu testende Wert vorliegt. Dies ist eine Alternative, da der Operator or verwendet wirdfloor die Eingabe verwendet wird.

Beide Lösungen funktionieren und verursachen keine Auffälligkeiten.


2

Ocaml, 45 Zeichen

Basierend auf der Lösung von @Leah Xue. Drei Leerzeichen könnten entfernt werden, und es ist etwas kürzer (~ 3 Zeichen), um die Funktion anstelle von if-then-else zu verwenden.

let rec o=function 0->0|x->(x mod 2)+(o(x/2))  


1

Scala, 86 Zeichen

object O extends App{def f(i:Int):Int=if(i>0)i%2+f(i/2)else 0
print(f(args(0).toInt))}

Verwendung: scala O 56432


1

D (70 Zeichen)

int f(string i){int k=to!int(i),r;while(k){if(k%2)r++;k/=2;}return r;}

1

R, 53 Zeichen

o=function(n){h=n%/%2;n%%2+if(h)o(h)else 0};o(scan())

Beispiele:

> o=function(n){h=n%/%2;n%%2+if(h)o(h)else 0};o(scan())
1: 56432
2: 
Read 1 item
[1] 8
> o=function(n){h=n%/%2;n%%2+if(h)o(h)else 0};o(scan())
1: 45781254
2: 
Read 1 item
[1] 11
> o=function(n){h=n%/%2;n%%2+if(h)o(h)else 0};o(scan())
1: 0
2: 
Read 1 item
[1] 0

Wenn die Eingabe der Nummer nicht Teil der Zeichenanzahl ist, sind es 43 Zeichen:

o=function(n){h=n%/%2;n%%2+if(h)o(h)else 0}

mit Testfällen

> o(56432)
[1] 8
> o(45781254)
[1] 11
> o(0)
[1] 0

1

OCaml, 52 Zeichen

let rec o x=if x=0 then 0 else (x mod 2) + (o (x/2))

1

Planen

Ich habe die Regeln ein wenig überarbeitet, um die Herausforderung zu erweitern. Die Funktion kümmert sich nicht um die Basis der Zahl, da sie eine eigene Binärskala verwendet. Ich war inspiriert von der Art und Weise, wie analoge numerische Konvertierungen funktionieren. Ich benutze dafür einfach die Rekursion:

(define (find-ones n)
  (define (nbits n)
    (let nbits ([i 2])
      (if (< i n) (nbits (* i 2)) i)))
  (let f ([half (/ (nbits n) 2)] [i 0] [n n])
    (cond [(< half 2) i]
      [(< n i) (f (/ half 2) i (/ n 2))]
      [else (f (/ half 2) (+ i 1) (/ n 2))])))

1

Ist das Lesen einer Zahl in eine Binärzahl oder das Drucken der Zahl aus einer Binärzahl nicht eine "eingebaute Basiskonvertierungsfunktion", die jede Antwort darüber ungültig macht, die printeine Ganzzahl ist? Wenn Sie das Lesen und Drucken einer Ganzzahl zulassen, wie es bei fast allen obigen Antworten der Fall ist , werde ich Behauptungen mit einer eingebauten popcountFunktion aufstellen :

Haskell, 50

In diesem Sommer wurde popCountdem Data.BitsModul für GHC v7.2.1 / v7.4.1 eine Routine hinzugefügt (siehe Tickets zu Primop und Bindung ).

import Data.Bits
main=interact$show.popCount.read

Ich kann die obigen Python- und Perl-Scores mit ihren GMPYoder GMP::MpzModulen für GMP leider nicht übertreffen , obwohl GMP auch eine Popcount-Funktion bietet .


1

JavaScript, 49 47 45 42 Bytes

for(n=prompt(o=0);n=n/2|0;o+=n%2);alert(o)

Demo: http://jsfiddle.net/hcYdx/4/

Edit 1: entfernen qund ~~zum Runden verwenden, 2 Zeichen speichern.

Edit 2: Verwenden Sie den |0Rundungsoperator ~~, um Klammern (2 Zeichen) zu speichern.

Bearbeiten 3: Vereinfachung n>0zu nund verbinden sich mit n=n/2|0bis zu ganzem Zustand zu machen; Jetzt haben Statement-Platz verschwendet :(


3
Ist das nicht |0ein bitweiser Operator?
Vilx

Technisch ja. Aber ich verwende es nur, um auf das nächste int zu runden, also bekomme ich keine bitweisen Vorteile :)
mellamokb

Es riecht so, als würde ich die Regeln biegen ... aber ich bin nicht der Richter.
Vilx

Eingang 1 gibt Ausgang 0.
Atreys

1
|ist bitweiser Operator ... ist nicht erlaubt. Zeit zu tun Math.round:-)
Jamie

1

Java 7, 36 Bytes

int b(Long a){return a.bitCount(a);}

Ausgerechnet dafür hat Java natürlich ...


Passt das nicht unter "Built-in Base-Conversion-Funktionen", die verboten sind?
FlipTack

@ Flp.Tkc Ich mache eigentlich keine Base-Konvertierung. Ich habe keine Ahnung, wie das bitCountunter der Haube funktioniert.
Poke

Dies scheint nur mit einem Bulitin, um die Arbeit zu erledigen, aber ok ...
FlipTack

@ Flp.Tkc Das ist ... genau das, was es ist? Ich schließe sogar alle benötigten Bibliotheken ein (es gibt keine). Dies zeigt die Stärke der Sprache! Verwandte Meta
Poke

1

TI-Basic (TI-84 Plus CE), 30 Byte

Prompt X
0→S
While X
S+remainder(2,X→S
int(X/2→X
End
S

TI-Basic ist eine Token-Sprache. Alle Token remainder(bestehen aus einem Byte , der Rest aus zwei


Willkommen auf der Seite!
DJMcMayhem

1

PHP, 36 Bytes

while($n){$o+=$n%2;$n/=2*1;}echo $o;

Angenommen, $nist die zu testende Zahl, zeigt einen PHP-Hinweis für $ound funktioniert nicht genau, wenn $n0 ist (gibt nichts aus).

PHP, 53 Bytes

$n=$argv[1];$o=0;while($n){$o+=$n%2;$n/=2*1;}echo $o;

Akzeptiert Befehlszeilen-Eingaben, zeigt keine PHP-Benachrichtigung an und gibt für 0 korrekt aus.


Willkommen auf der Seite! :)
DJMcMayhem
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.