31
\$\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\$
  • 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 at 21:50
  • 2
    \$\begingroup\$ @Shaggy I also definitely remember that challenge. \$\endgroup\$ – xnor Aug 7 at 3:47
  • 2
    \$\begingroup\$ are we to assume base-10 only? \$\endgroup\$ – Noone AtAll Aug 7 at 11:25
  • 3
    \$\begingroup\$ Is the eval needed in your example? \$\endgroup\$ – CSM Aug 7 at 18:29
  • 1
    \$\begingroup\$ you can also directly use grep -c 1 instead of grep -o 1| wc -l. \$\endgroup\$ – Nordine Lotfi Aug 8 at 5:57

45 Answers 45

9
\$\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
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I had the same in mind, but you beat me to it. A minor alternative is SΘO instead of J1¢. :) \$\endgroup\$ – Kevin Cruijssen Aug 6 at 10:36
  • \$\begingroup\$ You didn't had to change your original approach. The J1¢ is just as valid as SΘO. ;) \$\endgroup\$ – Kevin Cruijssen Aug 6 at 10:39
  • \$\begingroup\$ @KevinCruijssen Well, I read "a minor alternative" as "the way to make my answer more idiomatic"... \$\endgroup\$ – hi. Aug 6 at 10:41
7
\$\begingroup\$

Rust+itertools, 42 bytes

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

Try it in the Rust Playground!

| improve this answer | |
\$\endgroup\$
7
\$\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!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ In the Python 2 version, you can use back tick `range(a,b+1)` to save 3 bytes \$\endgroup\$ – Surculose Sputum Aug 6 at 17:58
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

| improve this answer | |
\$\endgroup\$
6
\$\begingroup\$

Octave, 29 28 27 bytes

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

Try it online!

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

R, 43 bytes

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

Try it online!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Nice! I had this at 44; regex were definitely the way to go. \$\endgroup\$ – Giuseppe Aug 6 at 18:17
5
\$\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
| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ Nice use of the --> operator ;-) \$\endgroup\$ – Neil Aug 6 at 11:09
  • 2
    \$\begingroup\$ 67 bytes \$\endgroup\$ – Olivier Grégoire Aug 6 at 19:17
  • 1
    \$\begingroup\$ @OlivierGrégoire Thanks! And 1 more byte by using ~- instead of -1 to get rid of the space. :) \$\endgroup\$ – Kevin Cruijssen Aug 6 at 21:17
  • 1
    \$\begingroup\$ 3 different forms of writing -1 in one answer? I approve! 😁 \$\endgroup\$ – Olivier Grégoire Aug 6 at 22:13
4
\$\begingroup\$

Ruby, 62 46 28 bytes

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

-18 bytes, courtesy of Dingus.

Try it online!

| improve this answer | |
\$\endgroup\$
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.

| improve this answer | |
\$\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.

| improve this answer | |
\$\endgroup\$
  • \$\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\$ – Kevin Cruijssen Aug 6 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 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\$ – Kevin Cruijssen Aug 6 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 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.

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

Kotlin, 49 bytes

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

Try it online!

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

Haskell, 26 bytes

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

Try it online!

| improve this answer | |
\$\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)
| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Perl 5 -p, 21 bytes

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

Try it online!

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

PHP, 46 45 bytes

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

Try it online!

| improve this answer | |
\$\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!

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Factor, 65 bytes

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

Try it online!

| improve this answer | |
\$\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
| improve this answer | |
\$\endgroup\$
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

| improve this answer | |
\$\endgroup\$
  • 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\$ – Mukundan314 Aug 7 at 10:45
2
\$\begingroup\$

Rust, 63 bytes

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

Try it online!

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

Scala, 29 bytes

_.to(_).mkString.count(_==49)

Try it online!

I like to abuse underscores.

| improve this answer | |
\$\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
| improve this answer | |
\$\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
| improve this answer | |
\$\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
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Since the list characters don't matter, you can just use backtick instead of jk. \$\endgroup\$ – FryAmTheEggman Aug 6 at 17:04
2
\$\begingroup\$

Wolfram Language (Mathematica), 29 bytes

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

Try it online!

| improve this answer | |
\$\endgroup\$
2
\$\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!

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Dart, 56 bytes

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

Try it online!

| improve this answer | |
\$\endgroup\$
2
\$\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

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

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.