20
\$\begingroup\$

Challenge :

Count the number of ones 1 in the binary representation of all number between a range.


Input :

Two non-decimal positive integers


Output :

The sum of all the 1s in the range between the two numbers.


Example :

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

I have only explained the first example otherwise it would have taken up a huge amount of space if I tried to explain for all of them.


Note :

  • Numbers can be apart by over a 1000
  • All input will be valid.
  • The minimum output will be one.
  • You can accept number as an array of two elements.
  • You can choose how the numbers are ordered.

Winning criteria :

This is so shortest code in bytes for each language wins.

\$\endgroup\$
  • 1
    \$\begingroup\$ OEIS A000788 \$\endgroup\$ – Leaky Nun Jun 5 '18 at 15:50
  • 1
    \$\begingroup\$ May we take the input as some kind of range type (IntRange in Kotlin, Range in Ruby)? \$\endgroup\$ – snail_ Jun 6 '18 at 4:03
  • \$\begingroup\$ Fun fact: case 1000 - 2000 yields 5938, but lower the case by 1000, the result also drops by 1000: 0-1000 = 4938. Proof \$\endgroup\$ – steenbergh Nov 16 '18 at 13:00

53 Answers 53

9
\$\begingroup\$

JavaScript (ES6), 38 bytes

Takes input in currying syntax (a)(b).

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

Try it online!

Commented

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
\$\endgroup\$
7
\$\begingroup\$

Python 2, 47 bytes

f=lambda x,y:y/x and bin(x).count('1')+f(x+1,y)

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ Clever trick to avoid >=... \$\endgroup\$ – Erik the Outgolfer Jun 5 '18 at 16:38
5
\$\begingroup\$

Java (JDK 10), 55 bytes

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

Try it online!

\$\endgroup\$
  • \$\begingroup\$ IntStream.range(a,b+1).map(Integer::bitCount).sum() \$\endgroup\$ – saka1029 Jun 6 '18 at 7:33
  • \$\begingroup\$ @saka1029 The imports are mandatory. So it's actually a->b->java.util.stream.IntStream.range(a,b+1).map(Integer::bitCount).sum(), for a whole 74 bytes. Even if the the import wasn't mandatory, the parameters are, so we'd have to write a->b->IntStream.range(a,b+1).map(Integer::bitCount).sum(), which counts as 57 bytes \$\endgroup\$ – Olivier Grégoire Jun 6 '18 at 7:38
  • \$\begingroup\$ You could also have a->b->IntStream.range(a,b+1).map(Long::bitCount).sum() for a 1 byte improvement. Marginal, but still one. \$\endgroup\$ – NotBaal Nov 14 '18 at 0:00
  • \$\begingroup\$ @NotBaal As mentioned by Olivier in the comment above, imports are mandatory, so it should be a->b->java.util.stream.IntStream.range(a,b+1).map(Long::bitCount).sum() (71 bytes). \$\endgroup\$ – Kevin Cruijssen Nov 15 '18 at 13:53
4
\$\begingroup\$

05AB1E, 4 bytes

ŸbSO

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Exactly the solution I got :). +1. \$\endgroup\$ – Magic Octopus Urn Jun 7 '18 at 18:37
4
\$\begingroup\$

Python 2, 45 bytes

lambda x,y:`map(bin,range(x,y+1))`.count('1')

Try it online!

\$\endgroup\$
4
\$\begingroup\$

MATL, 5 4 bytes

&:Bz

Try it online!

Thanks to Luis Mendo for saving a 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)

\$\endgroup\$
4
\$\begingroup\$

R, 41 34 bytes

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

Try it online!

Heavily inspired by the other R solution by ngm. This uses a different approach after the conversion to bits. Huge thanks to Giuseppe for hinting at a possible 34 bytes solution.

\$\endgroup\$
  • \$\begingroup\$ 34 bytes is possible! I forget where I saw the trick (I know I didn't come up with it) but there's a trickier conversion to a summable vector -- I'll post if you/ngm can't find it. \$\endgroup\$ – Giuseppe Jun 5 '18 at 17:36
  • \$\begingroup\$ @Giuseppe Indeed! \$\endgroup\$ – JayCe Jun 5 '18 at 18:14
  • 2
    \$\begingroup\$ I got it down to 37 bytes using a technique that might otherwise be useful. Also discovered that sd and var coerce anything they can to double. \$\endgroup\$ – ngm Jun 5 '18 at 18:14
  • \$\begingroup\$ You can use pryr::f to save 4 bytes: tio.run/##K/qfZvu/… \$\endgroup\$ – pajonk Jun 6 '18 at 7:27
  • \$\begingroup\$ @pajonk good point! But I'm trying to stick to the base R packages rather than R+pryr. I'm going to search on meta what can be considered "pure R". \$\endgroup\$ – JayCe Jun 6 '18 at 20:27
3
\$\begingroup\$

Jelly, 4 bytes

rBFS

Try it online!

Explanation

rBFS – Full program. Takes the two inputs from the commands line arguments.
r    – Range.
 B   – For each, convert to binary.
  FS – Flatten and sum.
\$\endgroup\$
  • \$\begingroup\$ O_o , that was fast ? \$\endgroup\$ – Muhammad Salman Jun 5 '18 at 15:27
  • \$\begingroup\$ @MuhammadSalman Well, the challenge is also kind of trivial IMO. \$\endgroup\$ – Mr. Xcoder Jun 5 '18 at 15:28
  • \$\begingroup\$ It may be, but an answer a minute after posting. \$\endgroup\$ – Muhammad Salman Jun 5 '18 at 15:30
  • 1
    \$\begingroup\$ @MuhammadSalman Yes, that's not really that fast for trivial challenges like this one; knowledge of Jelly also ensues. The real effort goes in e.g. the language of this month, QBasic. ;-) \$\endgroup\$ – Erik the Outgolfer Jun 5 '18 at 15:46
  • \$\begingroup\$ @EriktheOutgolfer : Can you answer this in QBasic / BrainF**k ? \$\endgroup\$ – Muhammad Salman Jun 5 '18 at 15:46
3
\$\begingroup\$

Pyth, 8 7 bytes

1 byte thanks to Mr. Xcoder.

ssjR2}F

Try it online!

\$\endgroup\$
3
\$\begingroup\$

APL (Dyalog Unicode), 16 bytes

{≢⍸(⍵⍴2)⊤⍺↓0,⍳⍵}

Try it online!

-1 thanks to H.PWiz.

Left argument = min
Right argument = max

\$\endgroup\$
3
\$\begingroup\$

Python 3, 56 54 52 bytes

This can be golfed more imo. -2 Bytes thanks to Mr.Xcoder -2 More bytes thanks to M. I. Wright

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

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Stax, 6 bytes

çy╠Ƽ☻

Run and debug it

\$\endgroup\$
2
\$\begingroup\$

Bash + common utilities, 50

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

Try it online!

Converting integers to binary strings is always a bit of pain in bash. The approach here is slightly different - convert the integers to octal, then replace each octal digit with the number of binary 1s it contains. Then we can just sum all converted digits

\$\endgroup\$
2
\$\begingroup\$

APL+WIN, 33 26 bytes

Prompts for vector of integers:

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

Try it online! Courtesy of Dalog Classic

Explanation:

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
\$\endgroup\$
2
\$\begingroup\$

R, 44 40 37 bytes

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

Try it online!

Previously:

function(a,b)sum(strtoi(intToBits(a:b)))
function(a,b)sum(as.integer(intToBits(a:b)))
\$\endgroup\$
2
\$\begingroup\$

Octave with Communication toolbox, 21 bytes

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

Try it online!

The code should be fairly obvious. Number of nonzero elements in the binary representation of each of the numbers in the range.

This would be @(a,b)nnz(dec2bin(a:b)-48) without the communication toolbox.

\$\endgroup\$
1
\$\begingroup\$

Husk, 4 bytes

Σṁḋ…

Try it online!

Explanation

Σṁḋ…
   …     Get the (inclusive) range.
 ṁḋ      Convert each to binary and concatenate.
Σ        Get the sum.
\$\endgroup\$
1
\$\begingroup\$

Ruby, 38 bytes

->a,b{("%b"*(b-a+1)%[*a..b]).count ?1}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

PHP, 97 Bytes

(sure this can be shortened, but wanted to use the functions)

Try it online

Code

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

Explanation

<?=
 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
\$\endgroup\$
  • \$\begingroup\$ it seems you can just do this \$\endgroup\$ – dzaima Jun 5 '18 at 17:07
  • \$\begingroup\$ For a second i absolutely forgot that you can set php function's name directly as a parameter :-( \$\endgroup\$ – Francisco Hahn Jun 5 '18 at 17:10
  • \$\begingroup\$ $argv[0] is the program name or "-"; You should work with $argv[1] and $argv[2]. And you can use join instead of implode, shortening this to 68 bytes: <?=substr_count(join(array_map(decbin,range($argv[1],$argv[2]))),1); \$\endgroup\$ – Titus Nov 11 '18 at 18:15
1
\$\begingroup\$

PowerShell, 72 bytes

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

Try it online!

Long because of the conversion to binary [convert]::ToString($_,2) and getting rid of the zeros -replace0. Otherwise we just take the input numbers, make a range $x..$y and for each number in the range convert it to binary, remove the zeros, take the .length thereof (i.e., the number of ones remaining), and add it to our $output.

\$\endgroup\$
  • \$\begingroup\$ try to use count instead length :) \$\endgroup\$ – mazzy Jul 2 '18 at 13:40
  • 1
    \$\begingroup\$ @mazzy count will always be 1 because we're counting the length of a string, not an array. \$\endgroup\$ – AdmBorkBork Jul 2 '18 at 13:43
  • \$\begingroup\$ string! you are right. thanks. -replace0 is smart. \$\endgroup\$ – mazzy Jul 2 '18 at 14:04
1
\$\begingroup\$

Haskell, 42 bytes

import Data.Bits
a%b=sum$popCount<$>[a..b]

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Pip, 10 bytes

$+JTB:a\,b

Try it online!

Explanation

            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 +)
\$\endgroup\$
1
\$\begingroup\$

Proton, 40 37 bytes

x=>y=>str(map(bin,x..y+1)).count("1")

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Charcoal, 10 bytes

IΣ⭆…·NN⍘ι²

Try it online! Link is to verbose version of code. Explanation:

     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
\$\endgroup\$
1
\$\begingroup\$

Brachylog, 8 bytes

⟦₂ḃᵐcọht

Try it online!

Explanation

⟦₂         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
\$\endgroup\$
1
\$\begingroup\$

Bash + coreutils, 38 32 bytes

seq -f2o%.fn $*|dc|tr -d 0|wc -c

Thanks to @Cowsquack for golfing off 6 bytes!

Try it online!

\$\endgroup\$
1
\$\begingroup\$

K (ngn/k), 19 13 bytes

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

Try it online!

{ } is a function with arguments x and y

!1+y is the list 0 1 ... y

x_ drops the first x elements

2\ encodes each int as a list of binary digits of the same length (this is specific to ngn/k)

+/ sum

+// sum until convergence; in this case sum of the sum of all binary digit lists

\$\endgroup\$
1
\$\begingroup\$

Perl 6, 32 30 bytes

-1 bytes thanks to Brad Gillbert

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

Try it online!

Explanation:

[…](@_)    #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
\$\endgroup\$
  • 1
    \$\begingroup\$ You can reduce it by one byte if you use [...](@_) instead of ($^a..$^b) \$\endgroup\$ – Brad Gilbert b2gills Jun 7 '18 at 17:00
1
\$\begingroup\$

J, 16, 15 14 bytes

1 byte saved thanks to FrownyFrog!

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

Try it online!

Explanation:

A dyadic verb, the left argument is the lower bound m of the range, the right one - the upper 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
\$\endgroup\$
  • \$\begingroup\$ Can you make it 14? \$\endgroup\$ – FrownyFrog Jun 7 '18 at 9:31
  • \$\begingroup\$ @FrownyFrog I'll try later today (apparently it's possible, since you are asking :) ) \$\endgroup\$ – Galen Ivanov Jun 7 '18 at 10:11
  • \$\begingroup\$ @FrownyFrog 15 for now, I'm still trying... \$\endgroup\$ – Galen Ivanov Jun 7 '18 at 14:28
  • 1
    \$\begingroup\$ 14 \$\endgroup\$ – FrownyFrog Jun 8 '18 at 1:42
  • \$\begingroup\$ @FrownyFrog Aah, so easy! I was thinking about }. but always in a fork and not in a hook. Thanks! \$\endgroup\$ – Galen Ivanov Jun 8 '18 at 6:51
1
\$\begingroup\$

QBasic, 95 93 83 82 bytes

@DLosc saved me some a lot of bytes!

Saved another byte using this technique!

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

Language of the Month FTW!

Explanation

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

Last testcase of 1000 to 2000 actually works, in QBasic 4.5 running on Dosbox: Hij doet het!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.