Zeroes in interval

14

1

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.

Filip Haglund

Posted 2016-01-29T20:17:30.763

Reputation: 1 789

2If 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 – 2016-01-29T20:23:41.040

4You might want to exclude unary as a base, or else this problem is trivial: get inputs, print 0. – Mego – 2016-01-29T20:29:56.037

Can you add some test cases for other bases? – Morgan Thrapp – 2016-01-29T20:34:23.123

3I think this would be more interesting if the base argument were required. "Base of your choice" is weird to me. – Alex A. – 2016-01-29T20:34:39.060

1Yes, @AlexA. but too late to change that now, 10 answers in. – Filip Haglund – 2016-01-29T20:53:23.737

Can we get input in unary? – lirtosiast – 2016-01-30T02:43:16.517

@ThomasKwa yes, unary input is ok – Filip Haglund – 2016-01-30T11:50:45.530

@Mego According to Wikipedia, "in order to represent a number N, an arbitrarily chosen symbol representing 1 is repeated N times". It would actually make the most sense to use 0, since there is no 2 symbol in base 2, no 3 in base 3, etc. So it makes sense that base 1 has no 1. – mbomb007 – 2017-03-23T13:32:01.087

Answers

17

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

lirtosiast

Posted 2016-01-29T20:17:30.763

Reputation: 20 331

7This is the second Jelly program I've written on my phone. – lirtosiast – 2016-01-29T20:44:55.250

13Damn, 1 byte? Give us a chance. – Rɪᴋᴇʀ – 2016-01-29T21:09:27.380

2This can be easily done in very few bytes in any other language. I say stick to the non-cheating version. – ETHproductions – 2016-01-29T21:13:11.260

13@ETHproductions The rules of the question explicitly allow doing this. Cheaty or not, it's the answer the rules call for. – Dennis – 2016-01-29T21:17:48.867

8

Python 2, 36 bytes

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

Credit to muddyfish for the `` trick.

Dantal

Posted 2016-01-29T20:17:30.763

Reputation: 91

1Welcome to Programming Puzzles & Code Golf! This is a nice first answer. :) – Alex A. – 2016-01-30T03:58:03.310

Wow! I didn't know it's working! – Dantal – 2016-01-31T02:23:58.093

6

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.

Adnan

Posted 2016-01-29T20:17:30.763

Reputation: 41 965

How does this work? – lirtosiast – 2016-01-29T21:17:22.260

@ThomasKwa Explanation added – Adnan – 2016-01-29T21:18:16.087

5

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

ETHproductions

Posted 2016-01-29T20:17:30.763

Reputation: 47 880

5

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.

Neil

Posted 2016-01-29T20:17:30.763

Reputation: 95 035

As I don't manage to get votes for my answer, I'll upvote yours (at least there my name inside) – edc65 – 2016-01-30T21:11:34.503

4

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

Mego

Posted 2016-01-29T20:17:30.763

Reputation: 32 998

3

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.

snail_

Posted 2016-01-29T20:17:30.763

Reputation: 1 982

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. – G B – 2017-03-23T13:11:25.000

3

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!

TanMath

Posted 2016-01-29T20:17:30.763

Reputation: 1 431

3

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)

Nelz

Posted 2016-01-29T20:17:30.763

Reputation: 321

that's dedication. – colsw – 2017-03-23T16:31:44.490

2

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);

Jörg Hülsermann

Posted 2016-01-29T20:17:30.763

Reputation: 13 026

Nice collection! Care to do a version 3a including base 64? :D – Titus – 2017-03-23T11:12:47.453

@Titus How is the order of base 64? Why not https://en.wikipedia.org/wiki/Ascii85 or make a little more with all printable ascii chars

– Jörg Hülsermann – 2017-03-23T12:11:56.533

2

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

Blue

Posted 2016-01-29T20:17:30.763

Reputation: 26 661

I think getting the bonus is worth it: /sjRQ}EE0 – FryAmTheEggman – 2016-01-29T20:48:53.493

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 – 2016-01-29T21:17:47.867

2

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.

Fatalize

Posted 2016-01-29T20:17:30.763

Reputation: 32 976

2

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

Alex A.

Posted 2016-01-29T20:17:30.763

Reputation: 23 761

2

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!

TanMath

Posted 2016-01-29T20:17:30.763

Reputation: 1 431

2

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>

edc65

Posted 2016-01-29T20:17:30.763

Reputation: 31 086

If you move the o='0' before the loop your code continues to work even when k<i. – Neil – 2016-01-30T19:58:42.117

@Neil nice, but the spec says (i ≤ k). Update I tried this but in fact it does not work for k<i – edc65 – 2016-01-30T20:32:51.783

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 – 2016-01-30T21:02:01.583

@Neil uh ok now I get it. It does not give a sensible answer but at least does not crash – edc65 – 2016-01-30T21:05:34.907

If I'm not mistaken, you can save 8 bytes with this: (i,k,b)=>eval("for(n=i;n<=k;++n)o+=n.toString(b)").match(/0/g).length. In this case, var o needs to be undefined in the context of execution. – Forcent Vintier – 2017-03-23T10:05:37.950

@ForcentVintier you need a 0 in the string to match, try calling the function with (1,9,10) – edc65 – 2017-03-23T21:59:44.773

My bad then! Thanks for the explanation :) – Forcent Vintier – 2017-03-24T09:04:32.307

1@ForcentVintier anyway after your input I revised the code saving some bytes – edc65 – 2017-03-24T10:42:03.933

1

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

lee

Posted 2016-01-29T20:17:30.763

Reputation: 200

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. – 0 ' – 2017-03-23T01:05:41.333

thank you 0, you are right but only a couple bytes. I believe my edited answer removes all the spaces I can. :) – lee – 2017-03-23T02:32:35.733

1

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.

Titus

Posted 2016-01-29T20:17:30.763

Reputation: 13 814

For fun: <?=0 supports unary and alphabetic. ;) – Titus – 2017-03-23T11:13:52.987

1

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

Morgan Thrapp

Posted 2016-01-29T20:17:30.763

Reputation: 3 574

1I literally never heard about the assert statement before this comment. Thanks mate! – sagiksp – 2017-03-23T06:04:05.163

1

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

Skyl3r

Posted 2016-01-29T20:17:30.763

Reputation: 399

1

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.

AdmBorkBork

Posted 2016-01-29T20:17:30.763

Reputation: 41 581

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. – colsw – 2017-03-23T16:29:33.303

@ConnorLSW Thanks! Don't need the quotes around '0', so that trimmed off a few more. – AdmBorkBork – 2017-03-24T13:13:20.673

nice one, I always forget powershell handles numbers like that. – colsw – 2017-03-24T14:21:26.223

1

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

Conor O'Brien

Posted 2016-01-29T20:17:30.763

Reputation: 36 228

1

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

Alex A.

Posted 2016-01-29T20:17:30.763

Reputation: 23 761

1

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.

nimi

Posted 2016-01-29T20:17:30.763

Reputation: 34 639

1

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

Luis Mendo

Posted 2016-01-29T20:17:30.763

Reputation: 87 464

1

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.

brainkz

Posted 2016-01-29T20:17:30.763

Reputation: 349

1

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

Brad Gilbert b2gills

Posted 2016-01-29T20:17:30.763

Reputation: 12 713

You know, that comment at the end of your code makes it seem longer... – ETHproductions – 2016-01-31T22:35:19.050

@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 – 2016-01-31T22:38:30.627

1

Mathematica, 39 bytes, 27.3 with bonus

Count[#~Range~#2~IntegerDigits~#3,0,2]&

A Simmons

Posted 2016-01-29T20:17:30.763

Reputation: 4 005

0

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);
}

HyperNeutrino

Posted 2016-01-29T20:17:30.763

Reputation: 26 575

@mbomb007 The problem is that formatting it this way renders the answer as 102 bytes on the Leaderboard in the question. – HyperNeutrino – 2017-03-23T13:36:54.060

That's a flaw with the leaderboard, not the post. Look at how most of the other answers are doing it the same way. – mbomb007 – 2017-03-23T13:37:43.527

@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. – HyperNeutrino – 2017-03-23T13:39:45.970

0

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.

NikoNyrh

Posted 2016-01-29T20:17:30.763

Reputation: 2 361