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.



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


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!


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)


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.


¡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.

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





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


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

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)))

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.


1

Casco , 4 bytes

Σṁḋ…

Pruébalo en línea!

Explicación

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


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

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.


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 +)


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

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


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


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

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

¿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


@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!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.