Imprima la cantidad de unidades en un número binario sin usar operadores bit a bit

14

Descripción

Dado un número, imprime la cantidad de 1s que tiene en representación binaria.

Entrada

Un número >= 0en la base 10 que no excederá el número más alto que su idioma pueda manejar.

Salida

La cantidad de 1s en representación binaria.

Condición ganadora

El código más corto gana.

No permitido

  • Operadores bit a bit. Se permiten otros operadores, como la suma y la multiplicación.
  • Funciones de conversión de base incorporadas.

Ejemplos

Input:     Ouput:

56432      8


Input:     Output:

45781254   11


Input:     Output:

0          0
pimvdb
fuente
¿Se permiten funciones? Quiero hacer una solución Java, pero escribir código completo es demasiado tedioso ...: /
HyperNeutrino
1
Supongo que no
usaré

Respuestas:

16

APL, 9 12 caracteres

+/2|⌊⎕÷2*⍳32

Esto supone que el intérprete usa números enteros de 32 bits y que ⎕IOse establece en 0 (lo que significa que la monádica comienza con 0, en lugar de 1). Usé la versión de 32 bits de Dyalog APL .

Explicación, de derecha a izquierda:

  • ⍳32genera un vector de los primeros 32enteros (como se explicó anteriormente, porque ⎕IOes 0, este vector comienza con 0).
  • *Es la función de potencia. En este caso, genera 2el poder de cada elemento del vector suministrado como su argumento correcto.
  • ÷es la función dividida por. Nos da (entrada del usuario evaluada) dividido por cada elemento del vector a su derecha (cada potencia de dos).
  • coloca cada elemento del argumento a su derecha.
  • 2| nos da el resto de cada elemento de a su derecha dividido por 2 .
  • /reduce (dobla) su argumento derecho usando la función a su izquierda +,.

Ya no son 9 personajes. :(

Versión antigua que rompe las reglas:

+/⎕⊤⍨32/2

Explicación, de derecha a izquierda:

  • 32/2: Replicar 2,32 tiempos.
  • conmuta la función diádica a su izquierda, que en este caso es ( es decir, X⊤⍨Yes equivalente aY⊤X ).
  • es la función de codificación Codifica el entero a su derecha en la base dada a su izquierda. Tenga en cuenta que, debido al operador de conmutación, se cambian los argumentos derecho e izquierdo. La base se repite para la cantidad de dígitos requeridos, por lo tanto32/2 .
  • es una función niládica que acepta la entrada del usuario y la evalúa.
  • +/reduce (dobla) su argumento correcto usando +. (Sumamos los 0 y los 1).
Dillon Cower
fuente
2
¿No rompe esto la Built-in base conversion functionsimpronta?
Gareth
Whoops! Perdí esa.
Dillon Cower
Gah! ¡Pensé que me había dado una oportunidad de pelear con mi programa J! :-) Buen trabajo.
Gareth
@Gareth: No me di cuenta hasta que leí tu explicación en este momento, ¡pero mi respuesta es casi idéntica a la tuya! Supongo que eso podría esperarse de APL y J. :)
Dillon Cower
11

Brainbool , 2

,.

La interpretación más razonable, en mi opinión (y lo que usan la mayoría de las respuestas) del "número más alto que su idioma es capaz de manejar" es "el mayor número que su idioma admite de forma nativa ". Brainbool es un derivado de brainfuck que usa bits en lugar de bytes, y toma entrada y salida en binario ( 0y 1caracteres) en lugar de códigos de caracteres. Por lo tanto 1, el número más grande admitido de forma nativa es , y el más pequeño 0, que tiene pesos de Hamming 1y 0respectivamente.

Brainbool fue creado en 2010, según Esolang.

lirtosiast
fuente
99
Sabía que debía haber existido, pero me llevó una hora clasificar los derivados de Brainfuck en Esolang para encontrar Brainbool.
lirtosiast
8

J, 13 caracteres

(+ el número de dígitos en el número)

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

Uso: reemplace el nen el programa con el número que se probará.

Ejemplos:

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

Probablemente haya una forma de reorganizar esto para que el número se pueda colocar al principio o al final, pero esta es mi primera entrada J y mi cabeza me duele un poco ahora.

Explicación (principalmente para que lo entienda en el futuro)

i.32 - crea una matriz de los números del 1 al 32

2^ - convierte la lista en las potencias de dos 1 a 4294967296

n% - divide el número de entrada por cada elemento en la lista

<. - redondea todos los resultados de división al siguiente número entero

2|- igual que %2en la mayoría de los idiomas - devuelve 0 si es par y 1 si es impar

+/ - totaliza los elementos en la lista (que ahora son solo 1s o 0s)

Gareth
fuente
Estaré encantado de votar esto una vez que se lea de stdin (o cualquier equivalente que tenga J).
Steven Rumbalski
Creo que lo mejor que puedo hacer (tal vez, dependiendo de averiguar cómo) es mover la entrada al final del programa. Sin embargo, ¿la entrada estándar no se menciona en la pregunta?
Gareth
Lo siento por no especificar la forma de entrada. Sería injusto cambiar las reglas ahora, así que aceptaré esta. ¡Lo mencionaré la próxima vez!
pimvdb
@pimvdb No hay problema, no fue una queja. Creo que con los programas J, aunque todo lo que puedes hacer es definir un verbo que funcione en la entrada dada. Sin embargo, no estoy seguro de cómo reorganizaría esto para hacer eso. Quizás JB o uno de los otros expertos de J podrían ayudarme con eso ...
Gareth
... y después de leer un poco más, ahora veo que estaba completamente equivocado acerca de la entrada estándar.
Gareth
8

Brainfuck, 53 personajes

Faltaba una solución obligatoria de Brainfuck, así que hice esta:

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

Toma el número de la celda 1 y coloca el resultado en la celda 6.

Versión no registrada y comentada:

[  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
  [-<<<<+>>>>]
  <<<<
]
Copiar
fuente
6

Python 2.6, 41 caracteres

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

nota: Mi otra respuesta usa lambda y recursión y esta usa un ciclo while. Creo que son lo suficientemente diferentes como para justificar dos respuestas.

Steven Rumbalski
fuente
6

Ruby, 38 caracteres.

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

Otra solución usando ruby ​​y el mismo enfoque recursivo que Steven.

Howard
fuente
5

GolfScript, 17 16 caracteres

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

Editar: la nueva versión guarda 1 carácter utilizando la operación de lista en lugar de doblar (la versión original era ~{.2%\2/.}do]{+}*, versión de conteo directo:) ~0\{.2%@+\2/.}do;.

Howard
fuente
5

C, 45

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

Nada realmente especial aquí para jugar golf en C: tipo de retorno implícito, tipo entero implícito para parámetros.

Señor llama
fuente
4

Python 2.6, 45 caracteres

b=lambda n:n and n%2+b(n/2) 
print b(input())
Steven Rumbalski
fuente
1
Se puede acortar por dos caracteres usando en deflugar de una lambda.
Konrad Rudolph
1
@KonradRudolph: En realidad, pierde la ventaja una vez que incluye la declaración de devolución.
Steven Rumbalski
Vaya, lo olvidé. Estúpido.
Konrad Rudolph el
No necesitas el print b(input()). Es aceptable devolver el valor y tomar "input" como argumentos para las funciones.
caird coinheringaahing
4

Perl, 45 43 36 Personajes

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

Gracias a Howard por 45-> 43, y al Usuario 606723 por 43-> 36.

PhiNotPi
fuente
Puede usar los $n=int($n/2)2 caracteres más cortos.
Howard
¿Estamos seguros de que necesitamos el int ()? $n=<>;while($n){$_+=$n%2;$n/=2}printEsto seguirá en bucle hasta que $ n / 2 finalmente se acerque lo suficiente a 0, pero ¿nos importa? ;)
user606723
@ user606723 Acabo de probar eso y parece funcionar perfectamente, al menos para cada caso hasta 1000.
PhiNotPi
3

Perl, 30 caracteres

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

Basado en la solución de PhiNotPi , con algo de golf extra. Ejecutar con perl -M5.010para habilitar Perl 5.10say .

Ilmari Karonen
fuente
¿La $=variable especial hace algo especial en su programa, o es simplemente otra variable ordinaria?
PhiNotPi
2
@PhiNotPi: $=solo toma valores enteros, por lo que usarlo me ahorra un int.
Ilmari Karonen
¿No debería ser el argumento de la línea de comandos parte del recuento de caracteres?
Soham Chowdhury
@SohamChowdhury: No según este metahilo .
Ilmari Karonen
3

Lisp común, 12 caracteres

(suponiendo un nombre de variable de 1 carácter, es decir: 11 + longitud de número)

No es una función de conversión de base, por lo que debería funcionar:

(logcount x)

Ejemplos:

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

(Usando GNU CLISP.)

Joanis
fuente
Bueno, no es exactamente lo que tenía en mente ver como respuesta :) No creo que pueda aceptar esto. Básicamente es solo otro caso de esto .
pimvdb
3

C, 61 60 57 53 caracteres

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

El cuerpo de la función solo tiene 38 caracteres. Editar : operador bit a bit eliminado Editar : poner printffuera del ciclo como se sugiere en los comentarios Editar : cambiar a declaración K&R; Además, esto ya no es específico de C99

sam hocevar
fuente
Ya veo bitwise !!!
Joanis
Lo siento, pero el operador AND también cuenta como un operador bit a bit.
pimvdb
@ M.Joanis: duh, gracias por notarlo. Fijo.
sam hocevar
1
Creo que podrías ahorrar algunos caracteres si cambias a K&R C. Si estás de acuerdo con eso.
JB
Podría acortar esto en cuatro caracteres moviendo la impresión fuera del bucle.
marinus
3

dc - 26 caracteres

Esto es bastante largo, principalmente debido a la falta de construcciones de bucle dc.

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

Sigue sumando el módulo 2 del número y dividiendo el número por hasta que llega a cero. Puede manejar enteros arbitrariamente largos.

Ejemplo:

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

C, 66 caracteres

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

Nota: requiere un compilador compatible con gcc o gcc (por ejemplo, ICC, clang).

Para algunas CPU se __builtin_popcountcompila a una sola instrucción (por ejemplo, POPCNTen x86).

Paul R
fuente
¿Es correcto que en __builtin_popcountrealidad solo implemente el conteo de 1s en sí mismo? Si es así, aunque no es estrictamente incorrecto de acuerdo con las reglas, sinceramente, no creo que sea una entrada justa.
pimvdb
Probablemente debería estipular esto en la pregunta si desea no permitir entradas que aprovechen las capacidades integradas de un idioma o compilador dado.
Paul R
Esto no es legal en C ++ porque en C ++ no puede omitir el tipo de retorno en main, ni usarlo printfsin incluirlo previamente.
celtschk
@celtschk: punto justo - editado el C++
Paul R
2

JavaScript, 78 72 71 caracteres

Publicaré mi solución inicial que se me ocurrió antes de publicar la pregunta también. Sin embargo, ya hay una respuesta JavaScript mucho mejor :)

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/

La idea proviene de ciertas "tarjetas de lectura de la mente" que le permiten obtener el número que otra persona tiene en mente, mostrándoles tarjetas y dejándoles decir en qué tarjetas su número es aparente.

Funciona porque cada número es una combinación única de 1s / 0s en binario. Mi solución verifica en qué "tarjetas" el número es aparente para determinar cuántas1 s tiene. Sin embargo, no es muy eficiente ...

Encontré este documento que describe la técnica de lectura de la mente.

pimvdb
fuente
2

Haskell (60 caracteres)

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

PHP, 57

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

Esto supone que $ntiene el valor a probar.

PHP, 55 (solución alternativa)

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

Nuevamente, esto supone que $ntiene el valor a ser probado. Esta es una alternativa porque usa el operador o parafloor la entrada.

Ambas soluciones funcionan y no causan avisos.

Arjan
fuente
2

Ocaml, 45 caracteres.

Basado en la solución de @Leah Xue. Se pueden eliminar tres espacios y es un poco más corto (~ 3 caracteres) para usar la función en lugar de if-then-else.

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

Mathematica 26

Count[n~IntegerDigits~2,1]
DavidC
fuente
1

Scala, 86 personajes

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

Gareth
fuente
1

D (70 caracteres)

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

R, 53 caracteres

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

Ejemplos:

> 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

Si ingresar el número no es parte del recuento de caracteres, entonces son 43 caracteres:

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

con casos de prueba

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

OCaml, 52 caracteres

let rec o x=if x=0 then 0 else (x mod 2) + (o (x/2))
Leah Xue
fuente
1

Esquema

Pulí las reglas un poco para agregar al desafío. La función no se preocupa por la base del número porque usa su propia escala binaria. Me inspiró la forma en que funciona la conversión analógica a numérica. Solo uso la recursión simple para esto:

(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))])))
Samuel Duclos
fuente
1

¿No es leer un número en binario o imprimir el número de binario una "función de conversión de base incorporada", invalidando así cada respuesta anterior que printes un número entero? Si permite leer e imprimir un número entero, como lo hacen casi todas las respuestas anteriores, entonces haré reclamos utilizando una función incorporadapopcount :

Haskell, 50

Se popCountagregó una rutina al Data.Bitsmódulo para GHC v7.2.1 / v7.4.1 este verano (ver tickets sobre el primop y el enlace ).

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

No puedo superar lo anterior Python y Perl puntajes con sus GMPYo GMP::Mpzmódulos de GMP por desgracia, a pesar de GMP sí ofrece una función popcount también.

Jeff Burdges
fuente
1

JavaScript, 49 47 45 42 bytes

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

Demostración: http://jsfiddle.net/hcYdx/4/

Edición 1: eliminar qy usar ~~para redondear, guardar 2 caracteres.

Edición 2: utilice el |0operador de redondeo en lugar de ~~guardar paréntesis (2 caracteres).

Editar 3: simplificar n>0a ny se combinan con n=n/2|0hacer que toda condición; ahora han desperdiciado espacio en la declaración :(

mellamokb
fuente
3
¿No es el |0operador bit a bit?
Vilx-
Técnicamente si. Pero lo estoy usando puramente redondear al int más cercana, por lo que ahora no recibo ningún beneficio bit a bit :)
mellamokb
Huele a doblarme las reglas ... pero no soy el juez.
Vilx-
La entrada 1 da la salida 0.
Atreys
1
|es operador bit a bit ... no está permitido. Hora de hacer Math.round:-)
Jamie
1

Java 7, 36 bytes

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

Porque, por supuesto, esto, de todas las cosas, es algo para lo que Java tiene incorporado ...

Dar un toque
fuente
¿No cabe esto en "funciones de conversión de base incorporadas", que están prohibidas?
FlipTack
@ Flp.Tkc En realidad no estoy haciendo conversión de base. No tengo idea de cómo bitCountfunciona bajo el capó.
Poke
Esto parece ser solo usar un bulitin para hacer el trabajo, pero está bien ...
FlipTack
@ Flp.Tkc Eso es ... ¿exactamente lo que es? Incluso estoy incluyendo todas las bibliotecas requeridas (no hay ninguna). ¡Esto demuestra la fuerza del lenguaje!meta relacionado
Poke
1

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

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

TI-Basic es un lenguaje tokenizado, todos los tokens pero remainder(son de un byte , el resto es dos

pizzapants184
fuente
Bienvenido al sitio!
DJMcMayhem
1

PHP, 36 bytes

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

Asume que $nes el número a ser probado, muestra un aviso de PHP $oy no funciona exactamente cuando $nes 0 (no muestra nada).

PHP, 53 bytes

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

Acepta la entrada de la línea de comandos, no muestra un aviso PHP y genera correctamente 0.

jstnthms
fuente
Bienvenido al sitio! :)
DJMcMayhem