Stampa la quantità di quelli in un numero binario senza utilizzare operatori bit a bit


14

Descrizione

Dato un numero, stampa la quantità di 1s che ha nella rappresentazione binaria.

Ingresso

Un numero >= 0in base 10 che non supererà il numero più alto che la tua lingua è in grado di gestire.

Produzione

La quantità di 1s nella rappresentazione binaria.

Condizioni vincenti

Vince il codice più corto.

Non consentito

  • Operatori bit a bit. Altri operatori, come addizione e moltiplicazione, sono ammessi.
  • Funzioni di conversione di base integrate.

Esempi

Input:     Ouput:

56432      8


Input:     Output:

45781254   11


Input:     Output:

0          0

Sono ammesse funzioni? Voglio creare una soluzione Java, ma scrivere il codice completo è troppo noioso ...: /
HyperNeutrino

1
Immagino che non
userò

Risposte:


16

APL, 9 12 caratteri

+/2|⌊⎕÷2*⍳32

Ciò presuppone che l'interprete utilizzi numeri interi a 32 bit e che ⎕IOsia impostato su 0 (il che significa che la monade inizia con 0, anziché con 1). Ho usato la versione a 32 bit di Dyalog APL .

Spiegazione, da destra a sinistra:

  • ⍳32genera un vettore dei primi 32numeri interi (come spiegato prima, poiché ⎕IOè 0, questo vettore inizia con 0).
  • *è la funzione di potenza. In questo caso, genera 2la potenza di ogni elemento del vettore fornito come argomento corretto.
  • ÷è la funzione divisa per. Ci dà (input dell'utente valutato) diviso per ogni elemento del vettore alla sua destra (ogni potenza di due).
  • pavimenta ogni elemento dell'argomento alla sua destra.
  • 2| ci dà il resto di ogni elemento alla sua destra diviso per 2 .
  • /riduce (piega) il suo argomento destro usando la funzione alla sua sinistra +,.

Non più di 9 personaggi. :(

Vecchia versione infrangibile:

+/⎕⊤⍨32/2

Spiegazione, da destra a sinistra:

  • 32/2: Replica 2, 32volte.
  • commuta la funzione diadica alla sua sinistra, che in questo caso è (cioè X⊤⍨Yè equivalente a Y⊤X).
  • è la funzione di codifica. Codifica il numero intero alla sua destra nella base data alla sua sinistra. Si noti che, a causa dell'operatore pendolarismo, vengono cambiati gli argomenti destro e sinistro. La base viene ripetuta per il numero di cifre richieste, quindi 32/2.
  • è una funzione niladica che accetta l'input dell'utente e lo valuta.
  • +/riduce (piega) il suo giusto argomento usando +. (Sommiamo gli 0 e gli 1).

2
Questo non rompe il Built-in base conversion functionscontrappunto?
Gareth,

Ops! Mi mancava quello.
Dillon Cower,

Gah! Pensavo di essermi dato una possibilità di combattere con il mio programma J! :-) Bel lavoro.
Gareth,

@Gareth: non me ne sono reso conto fino a quando non ho letto la tua spiegazione proprio ora, ma la mia risposta è praticamente identica alla tua! Immagino che ci si possa aspettare da APL e J. :)
Dillon Cower il

11

Brainbool , 2

,.

Secondo me (e ciò che la maggior parte delle risposte usa) l'interpretazione più ragionevole del "numero più alto che la tua lingua è in grado di gestire" è "il numero più grande che la tua lingua supporta in modo nativo ". Brainbool è un derivato di Brainfuck che utilizza bit anziché byte e accetta input e output in binari ( 0e 1caratteri) anziché in codici di caratteri. Il numero più grande supportato nativamente è quindi 1, e il più piccolo è 0, che hanno pesi di Hamming 1e 0rispettivamente.

Brainbool è stato creato nel 2010, secondo Esolang.


9
Sapevo che doveva esistere, ma mi ci è voluta un'ora di smistamento attraverso i derivati ​​Brainfuck su Esolang per trovare Brainbool.
lirtosiast,

8

J, 13 caratteri

(+ il numero di cifre nel numero)

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

Utilizzo: sostituire il n nel programma con il numero da testare.

Esempi:

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

Probabilmente c'è un modo di riorganizzare questo in modo che il numero possa essere posizionato all'inizio o alla fine, ma questa è la mia prima voce J e la mia testa mi fa un po 'male ora.

Spiegazione (principalmente per capirlo in futuro)

i.32 - crea una matrice dei numeri da 1 a 32

2^ - trasforma l'elenco in potenze da due 1 a 4294967296

n% - divide il numero di input per ciascun elemento nell'elenco

<. - arrotonda tutti i risultati di divisione al numero intero successivo

2|- come %2nella maggior parte delle lingue - restituisce 0 se pari e 1 se dispari

+/ - somma gli elementi nell'elenco (che ora sono solo 1s o 0s)


Sarò felice di votare questo una volta che avrà letto dallo stdin (o qualunque equivalente J abbia).
Steven Rumbalski,

Il meglio che potrei fare penso (forse, a seconda di come capire come) è spostare l'input alla fine del programma. L'input standard non è menzionato nella domanda però?
Gareth,

Mi dispiace per non aver specificato la modalità di input. Sarebbe ingiusto cambiare le regole ora, quindi accetterò questo. Lo citerò la prossima volta!
pimvdb,

@pimvdb Nessun problema, non è stato un reclamo. Penso che con i programmi J anche se tutto ciò che puoi fare è definire un verbo che opera sull'input dato. Non sono sicuro di come riorganizzerei questo per farlo però. Forse JB o uno degli altri esperti J potrebbero aiutarmi in questo ...
Gareth, il

... e dopo aver letto un po 'di più ora vedo che mi sbagliavo completamente sull'input standard.
Gareth,

8

Brainfuck, 53 personaggi

Mi mancava una soluzione Brainfuck obbligatoria, quindi ho creato questa:

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

Prende il numero dalla cella 1 e inserisce il risultato nella cella 6.

Versione non registrata e commentata:

[  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 caratteri

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

nota: la mia altra risposta usa lambda e ricorsione e questa usa un ciclo while. Penso che siano abbastanza diversi da giustificare due risposte.


6

Rubino, 38 caratteri

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

Un'altra soluzione che utilizza il rubino e lo stesso approccio ricorsivo di Steven.


5

GolfScript, 17 16 caratteri

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

Modifica: la nuova versione salva 1 carattere utilizzando l'operazione elenco anziché piega (versione originale era ~{.2%\2/.}do]{+}*, versione conteggio diretto:) ~0\{.2%@+\2/.}do;.


5

C, 45

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

Niente di veramente speciale qui per giocare a golf in C: tipo di ritorno implicito, tipo intero implicito per i parametri.


4

Python 2.6, 45 caratteri

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

1
Può essere abbreviato da due caratteri usando definvece di una lambda.
Konrad Rudolph,

1
@KonradRudolph: In realtà, perdi il vantaggio una volta inclusa la dichiarazione di reso.
Steven Rumbalski,

Oops, l'ho dimenticato. Stupido.
Konrad Rudolph,

Non hai bisogno del print b(input()). È accettabile restituire il valore e accettare "input" come argomenti per le funzioni.
caird coinheringaahing

4

Perl, 45 43 36 personaggi

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

Grazie a Howard per 45-> 43 e a User606723 per 43-> 36.


È possibile utilizzare $n=int($n/2)quali 2 caratteri più corti.
Howard,

Siamo sicuri di aver bisogno di int ()? $n=<>;while($n){$_+=$n%2;$n/=2}printQuesto continuerà a girare fino a quando $ n / 2 alla fine si avvicinerà abbastanza a 0, ma ci importa? ;)
user606723

@ user606723 L'ho appena provato e sembra funzionare perfettamente, almeno per ogni caso fino a 1000.
PhiNotPi

3

Perl, 30 caratteri

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

Basato sulla soluzione di PhiNotPi , con qualche golf in più. Esegui con perl -M5.010per abilitare la sayfunzione Perl 5.10 .


La $=variabile speciale fa qualcosa di speciale nel tuo programma o è solo un'altra variabile ordinaria?
PhiNotPi il

2
@PhiNotPi: $=accetta solo valori interi, quindi il suo utilizzo mi fa risparmiare un int.
Ilmari Karonen,

La riga di comando arg non dovrebbe far parte del conteggio dei caratteri?
Soham Chowdhury,

@SohamChowdhury: non per questo meta thread .
Ilmari Karonen,

3

Lisp comune, 12 caratteri

(assumendo un nome di variabile da 1 carattere, ovvero 11 + lunghezza del numero)

Non è una funzione di conversione di base, quindi dovrebbe funzionare:

(logcount x)

Esempi:

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

(Usando GNU CLISP.)


Beh, non esattamente quello che avevo in mente di vedere come una risposta :) Non credo di poterlo accettare. Fondamentalmente è solo un altro caso di questo .
pimvdb,

3

C, 61 60 57 53 caratteri

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

Il corpo della funzione ha solo 38 caratteri. Modifica : rimosso operatore bit a bit Modifica : printfesci dal ciclo come suggerito nei commenti Modifica : passa alla dichiarazione K&R; inoltre, questo non è più specifico per C99


Vedo bitally !!!
Joanis,

Mi dispiace ma l'operatore AND conta anche come operatore bit a bit.
pimvdb,

@ M.Joanis: duh, grazie per averlo notato. Fisso.
Sam Hocevar,

1
Penso che potresti risparmiare qualche personaggio se passassi a K&R C. Se stai bene.
JB

Puoi accorciarlo di quattro caratteri spostando la stampa fuori dal ciclo.
Marin

3

dc - 26 caratteri

Questo è piuttosto lungo, principalmente a causa della mancanza di costrutti loop dc.

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

Continua a sommare il modulo 2 del numero e dividendo il numero per fino a quando non raggiunge lo zero. Può gestire numeri interi arbitrariamente lunghi.

Esempio:

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

3

C, 66 caratteri

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

Nota: richiede un compilatore compatibile con gcc o gcc (ad es. ICC, clang).

Per alcune CPU viene __builtin_popcountcompilato in un'unica istruzione (ad es. POPCNTSu x86).


È corretto che in __builtin_popcountrealtà implementa solo il conteggio di 1s stesso? Se è così, anche se non è strettamente sbagliato secondo le regole, onestamente non penso che sia una voce giusta.
pimvdb,

Probabilmente dovresti specificarlo nella domanda se desideri impedire le voci che sfruttano le funzionalità integrate di un determinato linguaggio o compilatore.
Paul R,

Questo non è C ++ legale perché in C ++ non è possibile omettere il tipo restituito su main, né utilizzarlo printfsenza includere in precedenza.
Celtschk,

@celtschk: fair point - curato ilC++
Paul R

2

JavaScript, 78 72 71 caratteri

Pubblicherò la mia soluzione iniziale che mi è venuta in mente prima di pubblicare anche la domanda. Esiste già una risposta JavaScript molto migliore :)

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/

L'idea nasce da certe "carte che leggono la mente" che ti permettono di ottenere il numero che qualcun altro ha in mente, mostrando loro le carte e far loro dire su quali carte è evidente il loro numero.

Funziona perché ogni numero è una combinazione unica di 1s / 0s in binario. La mia soluzione verifica su quali "carte" sia evidente il numero in modo da determinare quante1 s ha. Non è molto efficiente, però ...

Ho trovato questo documento che delinea la tecnica di lettura della mente.


2

Haskell (60 caratteri)

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;

Questo presuppone che $n detenga il valore da testare.

PHP, 55 (soluzione alternativa)

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

Ancora una volta, questo presuppone che $ndetenga il valore da testare. Questa è un'alternativa perché utilizza l'operatore orfloor l'input .

Entrambe le soluzioni funzionano e non causano avvisi.


2

Ocaml, 45 caratteri

Basato sulla soluzione di @Leah Xue. Tre spazi potrebbero essere rimossi ed è leggermente più breve (~ 3 caratteri) per usare la funzione invece di if-then-else.

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


1

Scala, 86 caratteri

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

Uso: scala O 56432



1

R, 53 caratteri

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

Esempi:

> 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

Se l'inserimento del numero non fa parte del conteggio dei caratteri, allora è di 43 caratteri:

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

con casi di test

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

1

OCaml, 52 caratteri

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

1

schema

Ho perfezionato un po 'le regole da aggiungere alla sfida. La funzione non si preoccupa della base del numero perché utilizza la propria scala binaria. Sono stato ispirato dal modo in cui funziona la conversione da analogico a numerico. Uso solo la semplice ricorsione per questo:

(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

La lettura di un numero in binario o la stampa di un numero binario non è una "funzione di conversione di base integrata", invalidando così ogni risposta sopra quella che printè un numero intero? Se permetti di leggere e stampare un numero intero, come fanno quasi tutte le risposte di cui sopra, allora farò dichiarazioni usando a built popcountfunzione di :

Haskell, 50 anni

C'era una popCountroutine di aggiunta al Data.Bitsmodulo per la GHC v7.2.1 / v7.4.1 questa estate (vedi biglietti relativa alla primop e vincolante ).

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

Non posso battere i punteggi di Python e Perl sopra usando i loro moduli GMPYo GMP::Mpzper GMP purtroppo, anche se GMP offre anche una funzione popcount .


1

JavaScript, 49 47 45 42 byte

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

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

Modifica 1: rimuovi qe usa~~ per arrotondare, salva 2 caratteri.

Modifica 2: utilizzare l' |0operatore di arrotondamento anziché~~ per salvare le parentesi (2 caratteri).

Edit 3: semplificare n>0per ne si combinano con n=n/2|0per rendere intera condizione; ora hai sprecato lo spazio delle istruzioni :(


3
L' |0operatore non è un bit per bit?
Vilx-

Tecnicamente si. Ma lo sto usando puramente per arrotondare
all'int

Odora di piegarmi le regole ... ma io non sono il giudice.
Vilx-

L'ingresso 1 fornisce l'uscita 0.
Atreys,

1
|è un operatore bit per bit ... non è consentito. Tempo di fare Math.round:-)
Jamie

1

Java 7, 36 byte

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

Perché, ovviamente, questo è qualcosa che Java ha incorporato per ...


Questo non rientra nelle "funzioni di conversione di base integrate", che sono vietate?
FlipTack

@ Flp.Tkc In realtà non sto eseguendo la conversione di base. Non ho idea di come bitCountfunzioni sotto il cofano.
Poke

sembra solo usare un bulitin per fare il lavoro, ma ok ...
FlipTack

@ Flp.Tkc Ecco ... esattamente di cosa si tratta? Sto anche includendo tutte le librerie richieste (non ce ne sono). Questo sta dimostrando la forza della lingua! meta related
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 è un linguaggio tokenizzato, tutti i token ma remainder(sono a un byte , il resto è due


Benvenuti nel sito!
James,

1

PHP, 36 byte

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

Presuppone che $nsia il numero da testare, mostra un avviso PHP $oe non funziona esattamente quando $nè 0 (non genera nulla).

PHP, 53 byte

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

Accetta input da riga di comando, non mostra un avviso PHP e restituisce correttamente 0.


Benvenuti nel sito! :)
James,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.