14
\$\begingroup\$

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.

\$\endgroup\$
  • 2
    \$\begingroup\$ 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? \$\endgroup\$ – StephenTG Jan 29 '16 at 20:23
  • 4
    \$\begingroup\$ You might want to exclude unary as a base, or else this problem is trivial: get inputs, print 0. \$\endgroup\$ – Mego Jan 29 '16 at 20:29
  • \$\begingroup\$ Can you add some test cases for other bases? \$\endgroup\$ – Morgan Thrapp Jan 29 '16 at 20:34
  • 3
    \$\begingroup\$ I think this would be more interesting if the base argument were required. "Base of your choice" is weird to me. \$\endgroup\$ – Alex A. Jan 29 '16 at 20:34
  • 1
    \$\begingroup\$ Yes, @AlexA. but too late to change that now, 10 answers in. \$\endgroup\$ – Filip Haglund Jan 29 '16 at 20:53

29 Answers 29

17
\$\begingroup\$

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
\$\endgroup\$
  • 7
    \$\begingroup\$ This is the second Jelly program I've written on my phone. \$\endgroup\$ – lirtosiast Jan 29 '16 at 20:44
  • 13
    \$\begingroup\$ Damn, 1 byte? Give us a chance. \$\endgroup\$ – Rɪᴋᴇʀ Jan 29 '16 at 21:09
  • 2
    \$\begingroup\$ This can be easily done in very few bytes in any other language. I say stick to the non-cheating version. \$\endgroup\$ – ETHproductions Jan 29 '16 at 21:13
  • 13
    \$\begingroup\$ @ETHproductions The rules of the question explicitly allow doing this. Cheaty or not, it's the answer the rules call for. \$\endgroup\$ – Dennis Jan 29 '16 at 21:17
8
\$\begingroup\$

Python 2, 36 bytes

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

Credit to muddyfish for the `` trick.

\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to Programming Puzzles & Code Golf! This is a nice first answer. :) \$\endgroup\$ – Alex A. Jan 30 '16 at 3:58
  • \$\begingroup\$ Wow! I didn't know it's working! \$\endgroup\$ – Dantal Jan 31 '16 at 2:23
6
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ How does this work? \$\endgroup\$ – lirtosiast Jan 29 '16 at 21:17
  • \$\begingroup\$ @ThomasKwa Explanation added \$\endgroup\$ – Adnan Jan 29 '16 at 21:18
5
\$\begingroup\$

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

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.

\$\endgroup\$
  • \$\begingroup\$ As I don't manage to get votes for my answer, I'll upvote yours (at least there my name inside) \$\endgroup\$ – edc65 Jan 30 '16 at 21:11
4
\$\begingroup\$

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

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!

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

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)
\$\endgroup\$
  • \$\begingroup\$ that's dedication. \$\endgroup\$ – colsw Mar 23 '17 at 16:31
3
\$\begingroup\$

Ruby, 46 - 30% = 32.2 bytes

You could probably golf this more, but at least I get the 30% bonus!

->i,k,b{((i..k).map{|a|a.to_s b}*"").count ?0}

...or without the bonus (27 bytes.)

->i,k{([*i..k]*"").count ?0}

Tips are welcome, still learning this whole "Ruby" thing.

\$\endgroup\$
  • \$\begingroup\$ Nice answer, you don't need the splat operator when using map, this could save 1 byte. (i..k) is as good as [*i..k] in the first case. \$\endgroup\$ – G B Mar 23 '17 at 13:11
2
\$\begingroup\$

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

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

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!

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

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

\$\endgroup\$
  • \$\begingroup\$ I think getting the bonus is worth it: /sjRQ}EE0 \$\endgroup\$ – FryAmTheEggman Jan 29 '16 at 20:48
  • \$\begingroup\$ 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 \$\endgroup\$ – FryAmTheEggman Jan 29 '16 at 21:17
2
\$\begingroup\$

PHP, 50 Bytes

supports decimal only

<?=substr_count(join(range($argv[1],$argv[2])),0);

supports decimal and binary with Bonus 63

<?=substr_count(join(array_map([2=>decbin,10=>""][$argv[3]],range($argv[1],$argv[2]))),0);

supports decimal,hexadecimal, octal and binary with Bonus 77.7

<?=substr_count(join(array_map([2=>decbin,8=>decoct,10=>"",16=>dechex][$argv[3]],range($argv[1],$argv[2]))),0);

supports base 2 - 36 with Bonus 78.4

<?=substr_count(join(array_map(function($i){return base_convert($i,10,$_GET[2]);},range($_GET[0],$_GET[1]))),0);
\$\endgroup\$
  • \$\begingroup\$ Nice collection! Care to do a version 3a including base 64? :D \$\endgroup\$ – Titus Mar 23 '17 at 11:12
  • \$\begingroup\$ @Titus How is the order of base 64? Why not en.wikipedia.org/wiki/Ascii85 or make a little more with all printable ascii chars \$\endgroup\$ – Jörg Hülsermann Mar 23 '17 at 12:11
2
\$\begingroup\$

JavaScript (ES6), 50 (71 - 30%)

(n,k,b)=>eval("for(o=0;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=(n,k,b)=>eval("for(o=0;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>

\$\endgroup\$
  • \$\begingroup\$ If you move the o='0' before the loop your code continues to work even when k<i. \$\endgroup\$ – Neil Jan 30 '16 at 19:58
  • \$\begingroup\$ @Neil nice, but the spec says (i ≤ k). Update I tried this but in fact it does not work for k<i \$\endgroup\$ – edc65 Jan 30 '16 at 20:32
  • \$\begingroup\$ 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 !) \$\endgroup\$ – Neil Jan 30 '16 at 21:02
  • \$\begingroup\$ @Neil uh ok now I get it. It does not give a sensible answer but at least does not crash \$\endgroup\$ – edc65 Jan 30 '16 at 21:05
  • 1
    \$\begingroup\$ @ForcentVintier anyway after your input I revised the code saving some bytes \$\endgroup\$ – edc65 Mar 24 '17 at 10:42
1
\$\begingroup\$

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

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...

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

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

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

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.

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

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

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.

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

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
\$\endgroup\$
  • 1
    \$\begingroup\$ I literally never heard about the assert statement before this comment. Thanks mate! \$\endgroup\$ – sagiksp Mar 23 '17 at 6:04
1
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ You know, that comment at the end of your code makes it seem longer... \$\endgroup\$ – ETHproductions Jan 31 '16 at 22:35
  • \$\begingroup\$ @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. \$\endgroup\$ – Brad Gilbert b2gills Jan 31 '16 at 22:38
1
\$\begingroup\$

Mathematica, 39 bytes, 27.3 with bonus

Count[#~Range~#2~IntegerDigits~#3,0,2]&
\$\endgroup\$
1
\$\begingroup\$

C# 112 Bytes

int z(int i,int k)=>String.Join("",Enumerable.Range(i,k-i+1)).Count(c=>c=='0')
  1. Create a string with numbers from the first number up to the last number
  2. Count the zero characters in the string
\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG! I'm not super familiar with C# but I think you could probably save a few bytes if you removed some of the spaces. \$\endgroup\$ – 0 ' Mar 23 '17 at 1:05
  • \$\begingroup\$ thank you 0, you are right but only a couple bytes. I believe my edited answer removes all the spaces I can. :) \$\endgroup\$ – lee Mar 23 '17 at 2:32
1
\$\begingroup\$

PHP, 84 bytes *.7=58.8 (bases 2 to 36)

for(;($v=$argv)[2]>$a=$v[1]++;)$n+=substr_count(base_convert($a,10,$v[3]),0);echo$n;

or

for(;($v=$argv)[2]>$v[1];)$n+=substr_count(base_convert($v[1]++,10,$v[3]),0);echo$n;

takes decimal input from command line arguments; run with -r.

\$\endgroup\$
  • \$\begingroup\$ For fun: <?=0 supports unary and alphabetic. ;) \$\endgroup\$ – Titus Mar 23 '17 at 11:13
1
\$\begingroup\$

PowerShell, 56 54 51 48 42 bytes

param($i,$k)(-join($i..$k)-split0).count-1

Takes input, creates a range with $i..$k then -joins that together into a string, followed by a regex -split command that separates the string into an array by slicing at the 0s. We encapsulate that with ().count-1 to measure how many zeros. That's left on the pipeline, and output is implicit.

Saved 6 bytes thanks to @ConnorLSW

Try it online!


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

\$\endgroup\$
  • \$\begingroup\$ param($i,$k)(-join($i..$k)-split'0').Length-1 works for me, -3, or use .Count-1 to save even more, haven't tested that yet though. \$\endgroup\$ – colsw Mar 23 '17 at 16:29
  • \$\begingroup\$ @ConnorLSW Thanks! Don't need the quotes around '0', so that trimmed off a few more. \$\endgroup\$ – AdmBorkBork Mar 24 '17 at 13:13
  • \$\begingroup\$ nice one, I always forget powershell handles numbers like that. \$\endgroup\$ – colsw Mar 24 '17 at 14:21
0
\$\begingroup\$

Java 8, 102 bytes - 30% = 71.4

Why not.

(i,k,b)->{int j=0;for(;i<=k;i++)for(char c:Integer.toString(i,b).toCharArray())if(c==48)j++;return j;}

Without the bonus, 96 bytes (so the bonus actually improves my score!):

(i,k)->{int j=0;for(;i<=k;i++)for(char c:String.valueOf(i).toCharArray())if(c==48)j++;return j;}

This implements the following:

interface Function {
    public int apply(int i, int k, int b);
}
\$\endgroup\$
  • \$\begingroup\$ @mbomb007 The problem is that formatting it this way renders the answer as 102 bytes on the Leaderboard in the question. \$\endgroup\$ – HyperNeutrino Mar 23 '17 at 13:36
  • \$\begingroup\$ That's a flaw with the leaderboard, not the post. Look at how most of the other answers are doing it the same way. \$\endgroup\$ – mbomb007 Mar 23 '17 at 13:37
  • \$\begingroup\$ @mbomb007 I'm looking at the answers and I see a ton of different formats, some of which work with the leaderboard, some of which don't. \$\endgroup\$ – HyperNeutrino Mar 23 '17 at 13:39
0
\$\begingroup\$

Clojure, 50 49 bytes

#(count(re-seq #"0"(apply str(range %(inc %2)))))

Oh regex is shorter than filtering. Original:

#(count(filter #{\0}(apply str(range %(inc %2)))))

Very basic, uses the set of character \0 to remove others and counts how many were found.

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