36
\$\begingroup\$

Description

Count how many occurrences there are of the digit 1 between two given numbers \$[a, b]\$, inclusive.

For example, from 1 to 100 it should be 21:

1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 31, 41, 51, 61, 71, 81, 91, 100

The number 1 is repeated 21 times.

Rules

  1. Each number in the input list is guaranteed is an integer in the range \$0 \leq a \leq b < 2^{32}\$.
  2. The shortest answer in bytes wins.

Test cases

[1, 100] -> 21
[11, 200] -> 138
[123, 678] -> 182

Example

Here is my code using bash

eval echo {$1..$2}|grep -o 1|wc -l
\$\endgroup\$
10
  • 2
    \$\begingroup\$ @Giuseppe, close, yeah. But the one I'm thinking of definitely took no input and used decimal, not binary. Obviously, it was a terrible challenge but, if I can find it, it's a definite dupe target. It's also extremely likely that my stupid broken brain is lying to me and no such challenge exists! \$\endgroup\$
    – Shaggy
    Aug 6, 2020 at 21:50
  • 2
    \$\begingroup\$ @Shaggy I also definitely remember that challenge. \$\endgroup\$
    – xnor
    Aug 7, 2020 at 3:47
  • 2
    \$\begingroup\$ are we to assume base-10 only? \$\endgroup\$ Aug 7, 2020 at 11:25
  • 3
    \$\begingroup\$ Is the eval needed in your example? \$\endgroup\$
    – CSM
    Aug 7, 2020 at 18:29
  • 1
    \$\begingroup\$ you can also directly use grep -c 1 instead of grep -o 1| wc -l. \$\endgroup\$ Aug 8, 2020 at 5:57

51 Answers 51

10
\$\begingroup\$

05AB1E, 5 4 bytes

Thanks a lot to OP! Now I can save a byte

ŸSΘO

Try it online!

Explanation

Ÿ    Inclusive range
 S   Split the string into individual chars
  Θ  (Vectorizes) Does this character == "1"?
   O Sum the resulting list
\$\endgroup\$
3
  • \$\begingroup\$ I had the same in mind, but you beat me to it. A minor alternative is SΘO instead of J1¢. :) \$\endgroup\$ Aug 6, 2020 at 10:36
  • \$\begingroup\$ You didn't had to change your original approach. The J1¢ is just as valid as SΘO. ;) \$\endgroup\$ Aug 6, 2020 at 10:39
  • \$\begingroup\$ @KevinCruijssen Well, I read "a minor alternative" as "the way to make my answer more idiomatic"... \$\endgroup\$
    – user96495
    Aug 6, 2020 at 10:41
8
\$\begingroup\$

Python 2, 39 36 bytes

-3 bytes thanks to @SurculoseSputum

lambda a,b:`range(a,b+1)`.count('1')

Try it online!

Python 3, 42 40 bytes

-2 bytes thanks to @JoKing

lambda a,b:f"{*range(a,b),b}".count('1')

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ In the Python 2 version, you can use back tick `range(a,b+1)` to save 3 bytes \$\endgroup\$ Aug 6, 2020 at 17:58
7
\$\begingroup\$

Rust+itertools, 42 bytes

|a,b|(a..=b).join("").matches('1').count()

Try it in the Rust Playground!

\$\endgroup\$
6
\$\begingroup\$

APL (Dyalog Extended), 9 bytes

+/'1'=⍕⍤…

Try it online!

+/ sum

'1'= where the character is equal to

 the string representation

 of

 the range

\$\endgroup\$
6
\$\begingroup\$

Octave, 29 28 27 bytes

@(x,y)sum(mat2str(x:y)==49)

Try it online!

\$\endgroup\$
2
  • 2
    \$\begingroup\$ You can remove the square brackets. Also, does 48 work instead of "1"? \$\endgroup\$
    – Luis Mendo
    Aug 6, 2020 at 12:40
  • 2
    \$\begingroup\$ Luis probably meant 49, since 48 is zero? \$\endgroup\$ Aug 6, 2020 at 16:31
6
\$\begingroup\$

Java 8, 71 67 66 bytes

a->b->{var s="";for(;b>=a;)s+=b--;return~-s.split("1",-1).length;}

-4 bytes thanks to @OlivierGrégoire.

Try it online.

Explanation:

a->b->{                // Method with two integer inputs and integer return-type
  var s="";            //  String `s`, starting empty
  for(;b>=a;)          //  Loop `b` downwards in the range [`b`, `a`]:
    s+=b--;            //   And append `b` to to String `s`
  return~-s.split("1", //  Split String `s` on "1",
                  -1)  //  and keep empty trailing items
           .length;    //  Then get the amount of parts of this array
                       //  And decrease it by 1 with `~-`, before turning it as result
\$\endgroup\$
4
  • 2
    \$\begingroup\$ Nice use of the --> operator ;-) \$\endgroup\$
    – Neil
    Aug 6, 2020 at 11:09
  • 2
    \$\begingroup\$ 67 bytes \$\endgroup\$ Aug 6, 2020 at 19:17
  • 1
    \$\begingroup\$ @OlivierGrégoire Thanks! And 1 more byte by using ~- instead of -1 to get rid of the space. :) \$\endgroup\$ Aug 6, 2020 at 21:17
  • 1
    \$\begingroup\$ 3 different forms of writing -1 in one answer? I approve! 😁 \$\endgroup\$ Aug 6, 2020 at 22:13
5
\$\begingroup\$

R, 43 bytes

function(x,y)sum(unlist(gregexpr(1,x:y))>0)

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Nice! I had this at 44; regex were definitely the way to go. \$\endgroup\$
    – Giuseppe
    Aug 6, 2020 at 18:17
4
\$\begingroup\$

Ruby, 62 46 28 bytes

->c,d{[*c..d].join.count ?1}

-18 bytes, courtesy of Dingus.

Try it online!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ 28 bytes \$\endgroup\$
    – Dingus
    Aug 6, 2020 at 11:41
4
\$\begingroup\$

JavaScript (ES6), 44 bytes

Expects (a)(b).

a=>g=b=>b<a?0:(b+g).split(1).length-3+g(b-1)

Try it online!

How?

We use a recursive function g to count how many 1's we have in b and decrement b until it's lower than a.

In order to count the 1's, we have to coerce b to a string. We could do b+'' but it's shorter to use b+g. Because the source code of g itself contains two 1's, we subtract 3 instead of just 1 from the result of (b+g).split(1).length.

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

Retina 0.8.2, 36 32 bytes

\d+
$*_
(?<=(_+) _*)(?=\1)
$.'
1

Try it online! Link includes test cases. Explanation:

\d+
$*_

Convert a and b to unary, but use _ instead of 1 to avoid confusion. (In Retina 1 this would just be *, saving 2 bytes.)

(?<=(_+) _*)(?=\1)
$.'

At each boundary in b up to and including a from the end, insert the distance to the end in decimal, thus generating the range from b down to a.

1

Count the resulting number of 1s.

\$\endgroup\$
4
  • \$\begingroup\$ Out of curiosity: if it's shorter in Retina instead of Retina 0.8.2, why not just post that version instead? At least, that's what I usually do with 05AB1E / 05AB1E (legacy) / 2sable. Sometimes bytes can be saved by switching the language to a previous or later version. \$\endgroup\$ Aug 6, 2020 at 13:34
  • 1
    \$\begingroup\$ @KevinCruijssen I prefer to answer in Retina 0.8.2 if it's reasonably possible, only using Retina when I need a few feature, e.g. randomness. \$\endgroup\$
    – Neil
    Aug 6, 2020 at 15:41
  • \$\begingroup\$ Ah ok. Is there a reason why you prefer to answer in 0.8.2? Tbh, I was the same a few years back with only answering in Java 7, even though Java 8 with lambdas was always shorter, so I can definitely relate. :) \$\endgroup\$ Aug 6, 2020 at 15:42
  • \$\begingroup\$ Maybe I'm just trying to show off how well I can golf by deliberately using an "inferior" language? (Having said that, I've just golfed off 4 bytes...) \$\endgroup\$
    – Neil
    Aug 6, 2020 at 15:51
4
\$\begingroup\$

Google Sheets, 68

=SUM(ArrayFormula(LEN(REGEXREPLACE(""&SEQUENCE(A2-A1+1,1,A1),"[^1]",

Sheets auto-closes parens.

This is super slow at large ranges, but as this is Code Golf, we're here to optimize character count. My first attempt was to use JOIN(SEQUENCE(...)) to make one long string then count the 1's, but as it turns out, Sheets has a limit of 50000 characters, so that didn't work.

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

Kotlin, 49 bytes

{x:Int,y:Int->(x..y).sumBy{"$it".count{it=='1'}}}

Try it online!

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

Haskell, 26 bytes

a!b=sum[1|'1'<-show[a..b]]

Try it online!

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

MathGolf, 8 bytes

↨æ▒m┴Σ]Σ

Try it online.

Explanation:

↨         # Loop in the range [a,b] using the two implicit inputs a,b,
 æ        # and execute the following four commands:
  ▒       #  Convert the integer to a list of digits
   m      #  Map over each digit:
    ┴     #   And check which are equal to 1 (1 if 1; 0 otherwise)
     Σ    #  Get the sum of those checks
      ]   # After the loop, wrap all values on the stack into a list
       Σ  # And sum this list
          # (after which the entire stack joined together is output implicitly as result)
\$\endgroup\$
3
\$\begingroup\$

Perl 5 -p, 21 bytes

map$\+=y/1//,$_..<>}{

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ 20 bytes: $\+=y/1//for$_..<>}{ \$\endgroup\$
    – Zaid
    Aug 8, 2020 at 14:12
3
\$\begingroup\$

PowerShell, 40 bytes

$a,$b=$args
($a..$b|sls 1 -a|% m*).Count

Try it online!


PowerShell, 40 bytes

($args-join'..'|iex|sls 1 -a|% m*).Count

Try it online!

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

PHP, 46 45 bytes

fn($a,$b)=>substr_count(join(range($a,$b)),1)

Try it online!

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

C (gcc), 58 bytes

i;c;f(a,b){for(c=0;b/a;)for(i=a++;i;i/=10)c+=i%10==1;a=c;}

Try it online!

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

Factor, 65 bytes

: f ( a b -- n ) [a,b] [ number>string [ 49 = ] count ] map sum ;

Try it online!

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

K (oK), 19 17 bytes

Solution:

{+/"1"=,/$x_!1+y}

Try it online!

Explanation:

Range generation is inefficient (i.e. generate range 0..Y and then drop from front, rather than generating range X..Y) but saves 2 bytes.

{+/"1"=,/$x_!1+y} / the solution
{               } / lambda taking implicit x & y args
             1+y  / add 1 to y
            !     / range 0..N
          x_      / drop (_) x items from front
         $        / convert to string
       ,/         / flatten 
   "1"=           / is string equal to "1"?
 +/               / sum
\$\endgroup\$
1
  • \$\begingroup\$ Not worth it's own answer, but 16 bytes is possible in ngn/k. \$\endgroup\$
    – coltim
    Nov 14, 2020 at 21:57
3
\$\begingroup\$

JavaScript (ES6), 63 62 bytes

a=>b=>([...Array(b-a+1)].map((_,i)=>i+a)+'').split(1).length-1

Try it online

[...Array(b-a+1)] // an array of length b-a+1
map((_,i)=>i+a)   // fill it with numbers from a to b
+''               // convert it to a string with each number separated by a comma
.split(1)         // split at each 1
.length-1         // count the chunks and subtract 1

-1 byte thanks to @Jo King

\$\endgroup\$
2
  • \$\begingroup\$ Nice first solution! You can take input curry'ed to save a byte \$\endgroup\$
    – Jo King
    Aug 9, 2020 at 10:39
  • \$\begingroup\$ @JoKing appreciate that. I was reluctant to post since there were so many great solutions. \$\endgroup\$
    – adiga
    Aug 9, 2020 at 14:28
3
\$\begingroup\$

J, 19 16 bytes

-3 bytes thanks to Jonah!

1#.1=/&":[,-.&i.

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ 1#.1=/&":[,-.&i. for 16 bytes \$\endgroup\$
    – Jonah
    Sep 4, 2020 at 17:07
  • 1
    \$\begingroup\$ @Jonah Thank you, yours is much better! \$\endgroup\$ Sep 4, 2020 at 18:31
2
\$\begingroup\$

Japt, 5 bytes

The spec contradicts itself as to whether the range should be inclusive or not. If it shouldn't then replace õ with o.

õ ¬è1

Try it

\$\endgroup\$
1
  • 2
    \$\begingroup\$ You will need to add V after õ since the challenge now asks for inclusive range between a to b rather than inclusive range between 1 and a \$\endgroup\$ Aug 7, 2020 at 10:45
2
\$\begingroup\$

Rust, 63 bytes

|a,b|(a..=b).map(|x|format!("{}",x).matches('1').count()).sum()

Try it online!

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

MATL, 7 bytes

&:V1V=s

Try it online!

Explanation

&:V1V=s
     =s  % Count occurrences
   1V    % of '1' in
  V      % string of
&:       % inclusive range of input
\$\endgroup\$
2
\$\begingroup\$

Java (OpenJDK 8), 80 bytes

a->b->IntStream.range(a,b+1).flatMap(i->(""+i).chars()).filter(x->x==49).count()

Try it online!

Doesn't need much of an explanation, but here's one anyways:

Function<Integer, Function<Integer, Long>> f = 
    a -> b-> 
      IntStream
        .range(a,b+1) //Create an IntStream going from a to b
        .flatMap(i -> //Map every int i in that stream
          (""+i)      //Make it a string
          .chars()    //Turn that string to an IntStream
        )    //Flatten that
        .filter(x -> x == 49)  //Keep all the '1's
        .count();              //Find out how many '1's there are
\$\endgroup\$
2
\$\begingroup\$

Jelly, 5 bytes

rDFċ1

Try it online!

Explanation:

rDFċ1
r      range of the inputs
 DF    make decimal and flatten; list of all the digits in the range
   ċ1  count occurences of 1
\$\endgroup\$
2
\$\begingroup\$

Pyth, 8 7 bytes

-1 byte thanks to @FryAmTheEggman

/`}QE"1

Try it online!

Explanation

/`}QE"1
  }QE     # Inclusive range on input
 `        # string of the range ([1, 2, 3] -> "[1, 2, 3]")
/    "1   # count ones
\$\endgroup\$
1
  • \$\begingroup\$ Since the list characters don't matter, you can just use backtick instead of jk. \$\endgroup\$ Aug 6, 2020 at 17:04
2
\$\begingroup\$

Wolfram Language (Mathematica), 29 bytes

Tr@DigitCount[Range@##,10,1]&

Try it online!

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

Dart, 56 bytes

f(a,b)=>'1'.allMatches([for(;a<=b;a++)a].join()).length;

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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