contar unos en rango

20

Desafío :

Cuente el número de unidades 1en la representación binaria de todos los números entre un rango.


Entrada:

Dos enteros positivos no decimales


Salida:

La suma de todas las 1s en el rango entre los dos números.


Ejemplo:

4 , 7        ---> 8
4  = 100 (adds one)   = 1
5  = 101 (adds two)   = 3
6  = 110 (adds two)   = 5
7  = 111 (adds three) = 8

10 , 20     ---> 27
100 , 200   ---> 419
1 , 3       ---> 4
1 , 2       ---> 2
1000, 2000  ---> 5938

Solo he explicado el primer ejemplo; de lo contrario, habría ocupado una gran cantidad de espacio si hubiera intentado explicarlo a todos.


Nota :

  • Los números pueden estar separados por más de 1000
  • Toda entrada será válida.
  • El resultado mínimo será uno.
  • Puede aceptar el número como una matriz de dos elementos.
  • Puedes elegir cómo se ordenan los números.

Criterios ganadores:

Este es el por lo que gana el código más corto en bytes para cada idioma.

Muhammad Salman
fuente
1
OEIS A000788
Leaky Nun
1
¿Podemos tomar la entrada como algún tipo de rango ( IntRangeen Kotlin, Rangeen Ruby)?
snail_
Fun hecho: caso 1000 - 2000rinde 5938, pero menor el caso de 1000, el resultado también se reduce en 1000: 0-1000 = 4938. Prueba
steenbergh

Respuestas:

9

JavaScript (ES6), 38 bytes

Toma entrada en la sintaxis de curry (a)(b).

a=>b=>(g=c=>a>b?0:1+g(c^c&-c||++a))(a)

Pruébalo en línea!

Comentado

a => b => (         // given the input values a and b
  g = c =>          // g = recursive function taking c = current value
    a > b ?         // if a is greater than b:
      0             //   stop recursion and return 0
    :               // else:
      1 +           //   add 1 to the final result
      g(            //   and do a recursive call to g() with:
        c ^ c & -c  //     the current value with the least significant bit thrown away
        || ++a      //     or the next value in the range if the above result is 0
      )             //   end of recursive call
)(a)                // initial call to g() with c = a
Arnauld
fuente
5

Java (JDK 10) , 55 bytes

a->b->{int c=0;for(;a<=b;)c+=a.bitCount(b--);return c;}

Pruébalo en línea!

Olivier Grégoire
fuente
IntStream.range(a,b+1).map(Integer::bitCount).sum()
saka1029
@ saka1029 Las importaciones son obligatorias. Entonces, en realidad a->b->java.util.stream.IntStream.range(a,b+1).map(Integer::bitCount).sum(), es para un total de 74 bytes. Incluso si la importación no fuera obligatoria, los parámetros sí lo son, por lo que tendríamos que escribir a->b->IntStream.range(a,b+1).map(Integer::bitCount).sum(), que cuenta como 57 bytes
Olivier Grégoire
También podría tener a->b->IntStream.range(a,b+1).map(Long::bitCount).sum()una mejora de 1 byte. Marginal, pero sigue siendo uno.
NotBaal
@NotBaal Como mencionó Olivier en el comentario anterior, las importaciones son obligatorias, por lo que deberían ser a->b->java.util.stream.IntStream.range(a,b+1).map(Long::bitCount).sum()(71 bytes).
Kevin Cruijssen
4

MATL , 5 4 bytes

&:Bz

Pruébalo en línea!

¡Gracias a Luis Mendo por salvar un byte!

(implicit input a and b, a<b)
&:                              % two-element input range, construct [a..b]
  B                             % convert to Binary as a logical vector (matrix)
   z                            % number of nonzero entries
(implicit output of the result)

Giuseppe
fuente
4

R , 41 34 bytes

function(a,b)sum(intToBits(a:b)>0)

Pruébalo en línea!

Muy inspirado por la otra solución R de ngm . Esto utiliza un enfoque diferente después de la conversión a bits. Muchas gracias a Giuseppe por insinuar una posible solución de 34 bytes.

JayCe
fuente
¡34 bytes es posible! Olvidé dónde vi el truco (sé que no se me ocurrió), pero hay una conversión más complicada a un sumvector mable: publicaré si usted / ngm no puede encontrarlo.
Giuseppe
@Giuseppe De hecho!
JayCe
2
Lo bajé a 37 bytes usando una técnica que de otro modo podría ser útil. También descubrió eso sdy varcoaccionó todo lo que pudieron para duplicar.
ngm
Puede usar pryr::fpara guardar 4 bytes: tio.run/##K/qfZvu/…
pajonk
@pajonk buen punto! Pero estoy tratando de mantener los paquetes base R en lugar de R + pryr. Voy a buscar en meta lo que se puede considerar "R puro".
JayCe
3

Jalea , 4 bytes

rBFS

Pruébalo en línea!

Explicación

rBFS: programa completo. Toma las dos entradas de los argumentos de la línea de comandos.
r - Rango.
 B - Para cada uno, convertir a binario.
  FS: aplanar y sumar.
Sr. Xcoder
fuente
O_o, eso fue rápido?
Muhammad Salman
@MuhammadSalman Bueno, el desafío también es una especie de OMI trivial.
Sr. Xcoder
Puede ser, pero una respuesta un minuto después de la publicación.
Muhammad Salman
1
@MuhammadSalman Sí, eso no es realmente tan rápido para desafíos triviales como este; El conocimiento de Jelly también se produce. El verdadero esfuerzo va, por ejemplo, en el idioma de este mes, QBasic. ;-)
Erik the Outgolfer
@EriktheOutgolfer: ¿Puedes responder esto en QBasic / BrainF ** k?
Muhammad Salman
3

Python 3 , 56 54 52 bytes

Esto se puede jugar más imo. -2 Bytes gracias a Mr.Xcoder -2 Más bytes gracias a MI Wright

lambda a,b:''.join(map(bin,range(a,b+1))).count('1')

Pruébalo en línea!

Galletas de molino de viento
fuente
2

Bash + utilidades comunes, 50

jot -w%o - $@|tr 247356 1132|fold -1|paste -sd+|bc

Pruébalo en línea!

Convertir enteros en cadenas binarias siempre es un poco doloroso en bash. El enfoque aquí es ligeramente diferente: convierta los enteros en octal, luego reemplace cada dígito octal con el número de 1 binarios que contiene. Entonces podemos sumar todos los dígitos convertidos

Trauma digital
fuente
2

APL + WIN, 33 26 bytes

Indicaciones para el vector de enteros:

+/,((↑v)⍴2)⊤(1↓v)+0,⍳-/v←⎕

Pruébalo en línea! Cortesía de Dalog Classic.

Explicación:

v←⎕ prompt for input of a vector of two integers max first

(v←1↓v)+0,⍳-/ create a vector of integers from min to max

(↑v)⍴2 set max power of 2 to max 

⊤ convert integers to a matrix of binaries

+/, convert matrix to a vector and sum
Graham
fuente
2

R , 44 40 37 bytes

function(a,b)sum(c(0,intToBits(a:b)))

Pruébalo en línea!

Previamente:

function(a,b)sum(strtoi(intToBits(a:b)))
function(a,b)sum(as.integer(intToBits(a:b)))
ngm
fuente
2

Octava con caja de herramientas de comunicación, 21 bytes

@(a,b)nnz(de2bi(a:b))

Pruébalo en línea!

El código debería ser bastante obvio. Número de elementos distintos de cero en la representación binaria de cada uno de los números en el rango.

Esto sería @(a,b)nnz(dec2bin(a:b)-48)sin la caja de herramientas de comunicación.

Stewie Griffin
fuente
1

Casco , 4 bytes

Σṁḋ…

Pruébalo en línea!

Explicación

Σṁḋ…
   …     Get the (inclusive) range.
 ṁḋ      Convert each to binary and concatenate.
Σ        Get the sum.

fuente
1

PHP, 97 bytes

(seguro que esto se puede acortar, pero quería usar las funciones)

Pruébalo en línea

Código

<?=substr_count(implode(array_map(function($v){return decbin($v);},
 range($argv[0],$argv[1]))),1);

Explicación

<?=
 substr_count(   //Implode the array and count every "1"
  implode(
    array_map(function($v){return decbin($v);}, //Transform every decimal to bin
          range($argv[0],$argv[1])   //generate a range between the arguments
     )
),1);   //count "1"'s
Francisco Hahn
fuente
parece que puedes hacer esto
dzaima
Por un segundo, olvidé por completo que puede configurar el nombre de la función php directamente como parámetro :-(
Francisco Hahn
$argv[0]es el nombre del programa o "-"; Deberías trabajar con $argv[1]y $argv[2]. Y puede usar en joinlugar de implodeacortar esto a 68 bytes:<?=substr_count(join(array_map(decbin,range($argv[1],$argv[2]))),1);
Titus
1

PowerShell , 72 bytes

param($x,$y)$x..$y|%{$o+=([convert]::ToString($_,2)-replace0).length};$o

Pruébalo en línea!

Largo debido a la conversión a binario [convert]::ToString($_,2)y la eliminación de los ceros -replace0. De lo contrario, solo tomamos los números de entrada, hacemos un rango $x..$yy para cada número en el rango lo convertimos a binario, eliminamos los ceros, tomamos los .lengthmismos (es decir, el número de unos restantes) y los agregamos a nuestro $oresultado.

AdmBorkBork
fuente
trate de usar counten su lugar length:)
mazzy
1
@mazzy countsiempre será 1porque estamos contando el lengthde una cadena, no una matriz.
AdmBorkBork
¡cuerda! tienes razón. Gracias. -replace0es listo.
mazzy
1

Pip , 10 bytes

$+JTB:a\,b

Pruébalo en línea!

Explicación

            a and b are command-line args (implicit)
      a\,b  Inclusive range from a to b
   TB:      Convert to binary (: forces TB's precedence down)
  J         Join into a single string of 1's and 0's
$+          Sum (fold on +)
DLosc
fuente
1

Carbón de leña , 10 bytes

IΣ⭆…·NN⍘ι²

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

     NN     Input numbers
   …·       Inclusive range
  ⭆         Map over range and join
        ι   Current value
         ²  Literal 2
       ⍘    Convert to base as string
 Σ          Sum of digits
I           Cast to string
            Implicitly print
Neil
fuente
1

Brachylog , 8 bytes

⟦₂ḃᵐcọht

Pruébalo en línea!

Explicación

⟦₂         Ascending range between the two elements in the input
  ḃᵐ       Map to base 2
    c      Concatenate
     ọ     Occurrences of each element
      h    Head: take the list [1, <number of occurrences of 1>]
       t   Tail: the number of occurrences of 1
Fatalizar
fuente
1

K (ngn / k) , 19 13 bytes

{+//2\x_!1+y}

Pruébalo en línea!

{ }es una función con argumentos xyy

!1+y es la lista 0 1 ... y

x_ deja caer los primeros x elementos

2\ codifica cada int como una lista de dígitos binarios de la misma longitud (esto es específico de ngn / k)

+/ suma

+//suma hasta la convergencia; en este caso suma de la suma de todas las listas de dígitos binarios

ngn
fuente
1

Perl 6 , 32 30 bytes

-1 bytes gracias a Brad Gillbert

{[…](@_)>>.base(2).comb.sum}

Pruébalo en línea!

Explicación:

[…](@_)    #Range of parameter 1 to parameter 2
       >>    #Map each number to
                      .sum  #The sum of
                 .comb      #The string of
         .base(2)    #The binary form of the number
Jo King
fuente
1
Puede reducirlo en un byte si lo usa en [...](@_)lugar de($^a..$^b)
Brad Gilbert b2gills
1

J , 16, 15 14 bytes

¡1 byte guardado gracias a FrownyFrog!

+/@,@#:@}.i.,]

Pruébalo en línea!

Explicación:

Un verbo diádico, el argumento izquierdo es el límite inferior mdel rango, el derecho, el superior n.

            ,    append                      
             ]   n to the
          i.     list 0..n-1
         }.      drop m elements from the beginning of that list 
      #:@        and convert each element to binary 
    ,@           and flatten the table
 +/@             and find the sum
Galen Ivanov
fuente
¿Puedes hacerlo 14?
FrownyFrog
@FrownyFrog Lo intentaré más tarde hoy (aparentemente es posible, ya que estás preguntando :))
Galen Ivanov
@FrownyFrog 15 por ahora, todavía estoy intentando ...
Galen Ivanov
1
14
FrownyFrog
@FrownyFrog Aah, ¡tan fácil! Estaba pensando }.pero siempre en un tenedor y no en un gancho. ¡Gracias!
Galen Ivanov
1

QBasic, 95 93 83 82 bytes

@DLosc me salvó alguna una gran cantidad de bytes!

¡Ahorré otro byte usando esta técnica !

INPUT a,b
FOR i=a TO b
k=i
FOR j=i TO 0STEP-1
x=k>=2^j
s=s-x
k=k+x*2^j
NEXT j,i
?s

Idioma del mes FTW!

Explicación

INPUT a,b           Ask user for lower and upper bound
FOR i=a TO b        Loop through that range
k=i                 we need a copy of i to not break the FOR loop
FOR j=i TO 0STEP-1  We're gonna loop through exponents of 2 from high to low.
                    Setting the first test up for 4 to 2^4 (etc) we know we're overshooting, but that 's OK
x=k>=2^j            Test if the current power of 2 is equal to or smaller than k 
                    (yields 0 for false and -1 for true)
s=s-x               If k is bigger than 2^j, we found a 1, so add 1 to our running total s
                    (or sub -1 from the total s...)
k=k+x*2^j           Lower k by that factor of 2 if the test is true, else by 0
NEXT                Test the next exponent of 2
NEXT                process the next number in range
?s                  print the total

El último caso de prueba de 1000 a 2000 realmente funciona, en QBasic 4.5 que se ejecuta en Dosbox: Hij doet het!

Steenbergh
fuente