35
\$\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

50 Answers 50

1
2
2
\$\begingroup\$

Arn, 18 14 bytes

÷|˶‘○Øî9þæEƥ"

Explanation

Unpacked:

+\${=1}((1=>):|c

Ungolfed:

+\ Fold with addition
  ${ Filter with block
    =1 Equals one
  }
  (
    (
      1=> Range [1, in]
    )
    :| c Join with no separator
  ) Implicit, can be removed

Strings automatically coerced into array context, output implicit

\$\endgroup\$
1
  • \$\begingroup\$ Hi, User:ZippyMagician! \$\endgroup\$ Aug 13, 2020 at 10:08
2
\$\begingroup\$

><>, 44 bytes

|>:a%:1=&+&/&0
v&n;>~1+::{:})?!
>v,a^!?)0:-\

The wrong tool for the job, as ><> knows nothing about decimal notation.

Takes (b,a) on the stack.

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

Lua, 63 bytes

c,a,b=0,...for i=a,b do c=c+({('').gsub(i,1,0)})[2]end print(c)

Try it online!

Apparently, we can't use ... as a range for for. What a shame.

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

Pip, 8 bytes

1NSTa\,b

Inclusive range of a and b, converts to string, find number of 1's.

Try it online!

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

Husk, 5 bytes

#1ṁd…

Try it online!

Jelly, but reversed.

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

Japt, 6 bytes

õV ¬è1

Try it here

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

Scala, 29 21 bytes

_.to(_)+""count(49==)

Try it online!

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

Io, 78 bytes

Just generates a range, and then counts the occurances of 1's.

method(a,b,Range 1 to(b)asList select(i,i>=a)join asList select(i,i=="1")size)

Try it online!

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

Charcoal, 9 bytes

I№⪫…·NNω1

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

      N     First input as a number
     N      Second input as a number
   …·       Inclusive range
  ⪫    ω    Cast to string and join
 №      1   Count literal `1`s
I           Cast to string
            Implicitly print
\$\endgroup\$
1
\$\begingroup\$

Gaia, 6 bytes

U$¦_1C

Try it online!

U	| Inclusive range [a,b]
$¦_	| Flattened list of digits
1C	| Count 1s
\$\endgroup\$
1
\$\begingroup\$

Actually, 9 bytes

uax#$'1ac

Try it online!

Explanation

uax#      Push the inclusive range
    $     Turn it into a string
     '1ac Count the amount of ones
\$\endgroup\$
1
\$\begingroup\$

F# (.NET Core), 65 bytes

fun x y->Seq.sumBy(fun a->a.ToString().Split("1").Length-1){x..y}

Try it online!

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

shellutils, 26 bytes

A similar idea to the challenger's example

seq $1 $2|grep -o 1|wc -l

Explanation

seq prints all the numbers in the range given, increasing by 1 if not specified.

grep -0 1 prints all 1 characters, one on each line

wc -l prints the number of lines

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

x86-32 assembly (26 bytes)

    xor    edi, edi       ; 31 FF     Set edi = 0 (counter for result)
    lea    esi, [edi+10]  ; 8D 77 0A  Set esi = 10
notFinished:
    mov    eax, ecx       ; 89 C8     eax contains the number to be checked next
notZero:
    xor    edx, edx       ; 31 D2
    div    esi            ; F7 F6     Separate digit from current number
    cmp    dl, 1          ; 80 FA 01  Check if this digit was one
    jne    notOne         ; 75 01
    inc    edi            ; 47        When the digit was one, increase counter
notOne:
    test   eax, eax       ; 85 C0
    jnz    notZero        ; 75 F2     Loop until all digits of current number are checked
    cmp    ebx, ecx       ; 39 CB
    loopnz notFinished    ; E0 EC     Loop until end of range is reached
    ret                   ; C3

Online working example

Intel syntax is used here. The opcodes are given in the middle column between the source code and the comments. The parameters are transferred in registers:

  • ebx contains range start
  • ecx contains range end

The result is returned in the edi register.

Credit: Thanks to 640KB for pointing out that looping from high to low saves one byte here.

\$\endgroup\$
2
  • \$\begingroup\$ Very nice one! I think you can -1 byte by looping high to low and then using a loopnz instead of inc and jb. tpcg.io/geET58Ud. However, for machine code callable functions, a ret is required at the end (sorry), so that's +1 byte there. \$\endgroup\$
    – 640KB
    Aug 8, 2020 at 14:29
  • \$\begingroup\$ Thanks, don't know about this meta post yet. I've updated my answer. \$\endgroup\$
    – fcdt
    Aug 8, 2020 at 20:44
1
\$\begingroup\$

Clojure, 73 bytes

(defn h[s e](count(filter #(= \1 %)(into[](apply str(range s(inc e)))))))

Try it online!

Ungolfed:

(defn how-many-ones [start end]
  (count (filter #(= \1 %) (into [] (apply str (range start (inc end)))))))
\$\endgroup\$
1
\$\begingroup\$

Swift, 50 bytes

{($0...$1).flatMap{"\($0)".filter{$0=="1"}}.count}

Short explanation: Maps every number in the range to a string and filters every character which is equal to 1 and counts the resulting characters.

Try it online!

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

05AB1E, 4 bytes

ŸJ1¢

Try it online! Takes two lines of input, the first one being b and the second being a.

   ¢  # total number of
  1   # ones
   ¢  # in
 J    # joined elements of
Ÿ     # [a, ..., b]
\$\endgroup\$
1
\$\begingroup\$

Julia, 26 bytes

a->b->count("1",join(a:b))

expects f(a)(b)

Try it online!

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

Excel, 75 bytes

=SUM(LEN(SEQUENCE((F5-E5),,E5))-LEN(SUBSTITUTE(SEQUENCE((F5-E5),,E5),1,"")))

Not very efficient, but works. Sequence generates a sequence of integers, and using the length/substitute calculation the number of ones is calculated.

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

Vyxal, s, 4 bytes

ṡƛ1O

Try it Online!

Explained

ṡƛ1O;
ṡ       # Create an inclusive range between the two inputs
 ƛ      # For each item in that range:
  1O    #   Count the number of 1s
        # The 's' flag autosums t.o.s and implicitly prints.
\$\endgroup\$
1
2

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.