Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Your task is to write a function or program that takes two non-negative integers i and k (ik), and figure out how many zeroes you'd write if you wrote all whole numbers from i to k (inclusive) in your base of choice on a piece of paper. Output this integer, the number of zeroes, to stdout or similar.

-30% if you also accept a third argument b, the integer base to write down the numbers in. At least two bases must be handled to achieve this bonus.

  • You may accept the input in any base you like, and you may change the base between test cases.
  • You may accept the arguments i, k and optionally b in any order you like.
  • Answers must handle at least one base that is not unary.

Test cases (in base 10):

i k -> output
10 10 -> 1
0 27 -> 3
100 200 -> 22
0 500 -> 92

This is code-golf; fewest bytes win.

share|improve this question
1  
If you can go with whatever base you'd like from case to case, couldn't you do each in base k and print 0 or 1, depending on whether i = 0? – StephenTG Jan 29 at 20:23
3  
You might want to exclude unary as a base, or else this problem is trivial: get inputs, print 0. – Mego Jan 29 at 20:29
    
Can you add some test cases for other bases? – Morgan Thrapp Jan 29 at 20:34
2  
I think this would be more interesting if the base argument were required. "Base of your choice" is weird to me. – Alex A. Jan 29 at 20:34
1  
Yes, @AlexA. but too late to change that now, 10 answers in. – Filip Haglund Jan 29 at 20:53

23 Answers 23

Jelly, 1 byte

¬

This uses base k+2, in which case there's a single 0 iff i is 0. It takes two arguments, but applies the logical NOT to only the first one.

If we don't want to cheat:

7 bytes - 30% = 4.9

-1.1 points by @Dennis

rb⁵$¬SS

This gets the bonus.

             dyadic link:
r            inclusive range
 b⁵$           Convert all to base input.
    ¬          Vectorized logical NOT
     S         Sum up 0th digits, 1st digits, etc.
      S        Sum all values
share|improve this answer
7  
This is the second Jelly program I've written on my phone. – lirtosiast Jan 29 at 20:44
12  
Damn, 1 byte? Give us a chance. – Eᴀsᴛᴇʀʟʏ Iʀᴋ Jan 29 at 21:09
1  
This can be easily done in very few bytes in any other language. I say stick to the non-cheating version. – ETHproductions Jan 29 at 21:13
12  
@ETHproductions The rules of the question explicitly allow doing this. Cheaty or not, it's the answer the rules call for. – Dennis Jan 29 at 21:17

ES6, 91 86 - 30% = 60.2 bytes

(i,k,b=10)=>([...Array(k+1-i)].map((_,n)=>(i+n).toString(b))+'0').match(/0/g).length-1

Or save 3 (2.1) bytes if b doesn't need to default to 10.

Best non-bonus version I could do was 65 bytes:

(i,k)=>([...Array(k+1).keys()].slice(i)+'0').match(/0/g).length-1

Edit: Saved 5 bytes by using @edc65's zero-counting trick.

share|improve this answer
    
As I don't manage to get votes for my answer, I'll upvote yours (at least there my name inside) – edc65 Jan 30 at 21:11

Python, 36 bytes

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

Credit to muddyfish for the `` trick.

share|improve this answer
    
Welcome to Programming Puzzles & Code Golf! This is a nice first answer. :) – Alex A. Jan 30 at 3:58
    
Wow! I didn't know it's working! – Dantal Jan 31 at 2:23

05AB1E, 3 1 byte

Uses base k+2 like the Jelly answer, Code:

_

Explanation:

_  # Logical NOT operator

3 byte non-cheating version:

Code:

Ÿ0¢

Explanation:

Ÿ    # Inclusive range
 0¢  # Count zeroes

The bonus gives me 3.5 bytes due to a bug:

ŸB)0¢

Explanation:

Ÿ      # Inclusive range
 B     # Convert to base input
  )    # Wrap into an array (which should not be needed)
   0¢  # Count zeroes

Uses CP-1252 encoding.

share|improve this answer
    
How does this work? – lirtosiast Jan 29 at 21:17
    
@ThomasKwa Explanation added – Adnan Jan 29 at 21:18

Seriously, 10 bytes

'0,,u@xεjc

Explanation:

'0,,u@xεjc
'0,,u       push "0", i, k+1
     @x     swap i and k+1, range(i, k+1)
       εjc  join on empty string and count 0s

Try it online!

With bonus: 11.9 bytes

'0,,u@x,╗`╜@¡`Mεjc

Try it online!

Explanation:

'0,,u@x,╗`╜@¡`MΣc
'0,,u@x             push "0", range(i, k+1)
       ,╗           push b to register 0
         `   `M     map:
          ╜@¡         push b, push string of a written in base b
               Σc   sum (concat for strings), count 0s
share|improve this answer

Japt, 3 bytes

+!U

Uses base k+2, as the Jelly answer. There is a zero iff i==0. Test it online!

Better version, 10 8 bytes

UòV ¬è'0

This one uses base 10. Test it online!

Bonus version, 14 12 bytes - 30% = 8.4

UòV msW ¬è'0

Sadly, with the golfing I did, the bonus is no longer worth it... Test it online!

How it works

UòV msW ¬è'0   // Implicit: U = start int, V = end int, W = base
UòV            // Create the inclusive range [U..V].
    msW        // Map each item by turning it into a base-W string.
        ¬      // Join into a string.
         è'0   // Count the number of occurances of the string "0".
share|improve this answer

CJam, 12 10 3 bytes

li!

This uses the shortcut @ThomasKwa does.

If this is not allowed, then here is a 10 byte answer.

q~),>s'0e=

Nice and short! Works like @Mego's Seriously answer.

Thanks @Dennis!

Had fun writing my first CJam answer!

Try it here!

share|improve this answer

Julia, 48 bytes - 30% = 33.6

f(i,k,b)=sum(j->sum(c->c<49,[base(b,j)...]),i:k)

This is a function that accepts three integers and returns an integer. One of the arguments specifies the base, so this qualifies for the bonus.

Ungolfed:

function f(i, k, b)
    # For each j in the inclusive range i to k, convert j to base
    # b as a string, splat the string into a character array, and
    # compare each character to the ASCII code 49 (i.e. '1'). The
    # condition will only be true if the character is '0'. We sum
    # these booleans to get the number of zeros in that number,
    # then we sum over the set of sums to get the result.
    sum(j -> sum(c -> c < 49, [base(b, j)...]), i:k)
end

Implementing the bonus yields a score just barely better than the not implementing it (34 bytes):

f(i,k)=sum(c->c<49,[join(i:k)...])
share|improve this answer

Pyth, 6.3 bytes, with bonus (9 bytes - 30%)

/sjRQ}EE0

Explanation:

  jRQ     - [conv_base(Q, d) for d in V]
     }EE  - inclusive_range(eval(input), eval(input))
 s        - sum(^, [])
/       0 - ^.count(0)

Try it here

Or 7 bytes without the bonus:

/`}EE\0

Explanation:

  }EE   - inclusive_range(eval(input), eval(input))
 `      - repr(^)
/    \0 - ^.count("0")

Try it here

Or use a test suite

share|improve this answer
    
I think getting the bonus is worth it: /sjRQ}EE0 – FryAmTheEggman Jan 29 at 20:48
    
Ehh, it's the same code with a base conversion, I'm pretty sure you know what you're doing, just the problem of a bonus forcing you to try different stuff and count... :P – FryAmTheEggman Jan 29 at 21:17

Brachylog, 26 bytes

,{,.e?}?:1frcS:0xlI,Sl-I=.

Takes input as a list [i,k].

Explanation

,{    }?:1f                § Unify the output with a list of all inputs which verify the
                           § predicate between brackets {...} with output set as the input
                           § of the main predicate

  ,.e?                     § Unify the input with a number between i and k with the ouput
                           § being the list [i,k]

           rcS             § Reverse the list and concatenate everything into a single
                           § number (we reverse it to not lose the leading 0 if i = 0 when
                           § we concatenate into a single number). Call this number S.

              :0xlI        § Remove all occurences of 0 from S, call I the length of this new
                           § number with no zeros

                   ,Sl-I=. § Output the length of S minus I.
share|improve this answer

Jolf, 7 bytes

Replace with \x11. Try it here!

Zl♂sjJ0
   sjJ  inclusive range between two numeric inputs
  ♂      chopped into single-length elements
Zl    0  and count the number of zeroes
        implicitly printed
share|improve this answer

Lua 74 bytes

z,c=io.read,""for a=z(),z()do c=c..a end o,b=string.gsub(c,"0","")print(b)

There's gotta be a more effective way to do this...

I thought I was really onto something here:

c,m,z=0,math,io.read for a=z(),1+z()do c=c+((m.floor(a/10))%10==0 and 1 or a%100==0 and 1 or a%10==0 and 1 or 0) end print(c)

But alas... It keeps getting longer and longer as I realize there's more and more zeroes I forgot about...

share|improve this answer

APL, 22 bytes

{+/'0'⍷∊0⍕¨(⍺-1)↓⍳⍵}

This is a monadic function that accepts the range boundaries on the left and right and returns an integer.

Ungolfed:

           (⍺-1)↓⍳⍵}  ⍝ Construct the range ⍺..⍵ by dropping the first
                      ⍝ ⍺-1 values in the range 1..⍵
       ∊0⍕¨           ⍝ Convert each number to a string
{+/'0'⍷               ⍝ Count the occurrences of '0' in the string

Try it here

share|improve this answer

Haskell, 29 bytes

i#k=sum[1|'0'<-show=<<[i..k]]

I'm using base 10.

Usage example: 100 # 200 -> 22

How it works: turn each element in the list from i to k into it's string representation, concatenate into a single string, take a 1 for every char '0' and sum those 1s.

share|improve this answer

Seriously, 2 bytes

This might be taking the Jelly answer trick to the limit, but here is a simple 2 byte Seriously answer.

,Y

Try it online!

share|improve this answer

JavaScript (ES6), 54 (77 - 30%)

(i,k,b)=>eval("o='0';for(n=i;n<=k;++n)o+=n.toString(b)").match(/0/g).length-1

No bonus, base k+2 is 10 bytes (i,k)=>+!i

No bonus, unary is 8 bytes (i,k)=>0

TEST

f=(i,k,b)=>eval("o='0';for(n=i;n<=k;++n)o+=n.toString(b)").match(/0/g).length-1

function go() {
  var i=I.value.match(/\d+/g)
  R.textContent = f(i[0],i[1],i[2])
}

go()
i,k,b:<input id=I value='0,500,10' oninput="go()">
<span id=R></span>

share|improve this answer
    
If you move the o='0' before the loop your code continues to work even when k<i. – Neil Jan 30 at 19:58
    
@Neil nice, but the spec says (i ≤ k). Update I tried this but in fact it does not work for k<i – edc65 Jan 30 at 20:32
    
Well, it worked for me (and I know the spec guarantees that i <= k, but your code crashes when k < i; by comparison my code only crashes when k < i - 1 !) – Neil Jan 30 at 21:02
    
@Neil uh ok now I get it. It does not give a sensible answer but at least does not crash – edc65 Jan 30 at 21:05

Python 3, 52.

Tried to implement the bonus, but it doesn't seem to be worth it.

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

With test cases:

assert f(10, 10) == 1
assert f(0, 27) == 3
assert f(100, 200) == 22
assert f(0, 500) == 92
share|improve this answer

PowerShell, 56 54 51 48 bytes

param($i,$k)($i..$k-join''-replace'[^0]').length

Takes input, creates a range with $i..$k then -joins that together into a string, followed by a regex -replace command that swaps everything not-a-zero with nothing. We encapsulate that with ().length to measure how many zeros remain.


Older, 54 bytes

param($i,$k)([char[]]($i..$k-join'')|?{$_-eq48}).count

Takes input, constructs a range $i..$k, -joined together, then casts that range as a char-array. We pipe that into ? (an alias for Where-Object) which selects only those characters that -equal ASCII 48 (i.e., '0'). That will output a collection, which we encapsulate with ().count to output the number of elements thus returned.


Base-handling in PowerShell is limited and doesn't support arbitrary bases, so I'm not going for the bonus.

share|improve this answer

MATL, 7 (10 bytes − 30% bonus)

2$:i:qYA~z

Try it online!

This works in release 11.0.2, which is earlier than this challenge.

Explanation

2$:      % implicitly input two numbers and generate inclusive range
i:q      % input base b and generate vector [0,1,...,b-1]
YA       % convert range to base b using symbols 0,1,...,b-1. Gives 2D array
~        % logical negation. Zeros become 1, rest of symbols become 0
z        % number of nonzero elements in array
share|improve this answer

Matlab: 27 bytes

@(q,w)nnz(num2str(q:w)==48)

creates a vector from lower number to larger one, then converts all numbers to string and counts all the '0' symbols.

share|improve this answer

T-SQL, 394 Bytes (No bonus)

I figure 'why not', right?

DECLARE @i INT, @k INT SET @i = 100 SET @k = 200  WITH g AS (SELECT @i AS n UNION ALL SELECT n+1 FROM g WHERE n+1<=@k ) SELECT LEN(n) AS c FROM (SELECT STUFF((SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(n, 1, ''), 2, ''), 3, ''), 4, ''), 5, ''), 6, ''), 7, ''), 8, ''), 9, ''), ' ', '') FROM g FOR XML PATH ('')) ,1,0,'') n ) a OPTION (maxrecursion 0)

And the friendly one:

-- CG!

DECLARE @i INT, @k INT 
SET @i = 100
SET @k = 200

WITH g AS 
(
    SELECT @i AS n
    UNION ALL
    SELECT n+1 FROM g WHERE n+1<=@k
)

SELECT LEN(n) AS c FROM 
(
    SELECT 
        STUFF((SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(n, 1, ''), 2, ''), 3, ''), 4, ''), 5, ''), 6, ''), 7, ''), 8, ''), 9, ''), ' ', '')
FROM g FOR XML PATH ('')) ,1,0,'') n
) a

OPTION (maxrecursion 0)
share|improve this answer

Perl 6, 23 bytes

{+($^i..$^k).comb(/0/)}
  1. creates a Range ( $^i..$^k )
  2. joins the values with spaces implicitly ( .comb is a Str method )
  3. creates a list of just the zeros ( .comb(/0/) )
  4. returns the number of elems in that list ( + )

Usage:

my &zero-count = {…}

for (10,10), (0,27), (100,200), (0,500), (0,100000) {
  say zero-count |@_
}
1
3
22
92
38895
share|improve this answer
    
You know, that comment at the end of your code makes it seem longer... – ETHproductions Jan 31 at 22:35
    
@ETHproductions I usually do that so that if I come up with more than one way to do things that I can see if it is shorter than others. I just keep adding more ways to do it until I come up with what I think is the shortest way. – Brad Gilbert b2gills Jan 31 at 22:38

Mathematica, 39 bytes, 27.3 with bonus

Count[#~Range~#2~IntegerDigits~#3,0,2]&
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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