Where are Champernowne's zeroes?

23

Consider the infinite string of all nonnegative decimal integers concatenated together in order (akin to Champernowne's constant):

0123456789101112131415161718192021222324252627282930...979899100101102103...

Write a program or function that takes in a nonnegative integer that indexes (0-based) into this infinite string. Output a truthy value if the digit indexed is 0, otherwise output a falsy value if the digit is 1-9.

The shortest code in bytes wins.

The first 25 truthy-producing inputs are:

0
11
31
51
71
91
111
131
151
171
191
192
194
197
200
203
206
209
212
215
218
222
252
282
312

Kudos if your program is memory effecient, but this is not a requirement.

Calvin's Hobbies

Posted 2016-08-28T13:09:50.367

Reputation: 84 000

9https://oeis.org/A031287 – Martin Ender – 2016-08-28T14:15:14.130

is it not better that program or that function return the digit of that array from its index [not only if that is 0 or not]? – RosLuP – 2016-08-28T17:24:49.580

Related: Row of natural numbers

– Dennis – 2016-08-28T18:33:09.937

I can't understand what this question is asking at all lol can someone explain it – Shaun Wild – 2016-09-01T11:26:34.163

Answers

12

Haskell, 25 bytes

(<'1').((show=<<[0..])!!)

Usage example: (<'1').((show=<<[0..])!!) 312 -> True

nimi

Posted 2016-08-28T13:09:50.367

Reputation: 34 639

7

05AB1E, 5 bytes

Code:

ÝJ¹è_

Explanation:

Ý      # Get the list [0 .. input].
 J     # Join the list.
  ¹    # Get the first input again.
   è   # Get the character on that index.
    _  # Logical negate (0 -> 1, everything else -> 0).

Uses the CP-1252 encoding. Try it online!

Adnan

Posted 2016-08-28T13:09:50.367

Reputation: 41 965

7

Mathematica, 42 40 bytes

(0@@Join@@IntegerDigits@Range@#)[[#]]<1&

Anonymous function. Takes a number as input and returns either True or False as output. A longer, yet more efficient(?) solution:

RealDigits[ChampernowneNumber[],10,1,-#][[1,1]]<1&

LegionMammal978

Posted 2016-08-28T13:09:50.367

Reputation: 15 731

5

CJam, 9 bytes

{_),s=~!}

This is an unnamed block (function) which takes in an integer and returns 0 or 1 accordingly.

Explanation:

{       }        Defines a block
 _               Copy input n
  ),             Increment n and take range
    s            Convert to string - for a list of numbers this concatenates
                 the digits
     =           Index, getting nth digit
      ~          Evaluate the digit character into a number
       !         Logical negation

Online interpreter. Note that ~ evaluates a block. Alternative, you can run this test suite which uses , to filter the first 1000 numbers for truthy values.

Sp3000

Posted 2016-08-28T13:09:50.367

Reputation: 58 729

4

MATL, 11 bytes

Qt:qVXzw)U~

Try it Online!

Explanation:

    % Implicitly grab input as an integer (N)
Qt  % Add 1 and duplicate
:q  % Create an array from [0 ... N]
V   % Convert each entry to a string (places spaces between each number)
Xz  % Remove all whitespace
w)  % Get the N+1 element of the string (since MATL uses 1-based indexing natively)
U~  % Convert the result back to a number and negate which yields TRUE if it was '0' and
    % FALSE otherwise

Suever

Posted 2016-08-28T13:09:50.367

Reputation: 10 257

4

Brachylog, 10 8 bytes

2 bytes thanks to Fatalize.

y@ec:?m0

Try it online!

y@ec:?m0

y         range from 0 to Input, inclusive,
 @e       the digits of every number in that range,
   c      concatenated
    :?m   the Input-th digit
       0  is zero.

Leaky Nun

Posted 2016-08-28T13:09:50.367

Reputation: 45 011

@e vectorizes so y@ec:?m0 works, to save 2 bytes. – Fatalize – 2016-08-28T14:32:21.343

@Fatalize How many other operators vectorize? – Leaky Nun – 2016-08-28T14:32:54.727

Only #0, #1, #+, #_, #> and #< vectorize like @e does. Some of the predicates that vectorize such as + or * don't vectorize recursively to the lowest list level, and don't perform the same thing depending on the structure of the input. – Fatalize – 2016-08-28T14:36:07.117

4

Perl 6, 26 25 bytes

{!+map(|*.comb,0..*)[$_]}

A lambda that takes a number as input and returns a True or False.

Memory-efficient.

How it works

  1. 0..* – Construct the range from 0 to infinity.
  2. map(|*.comb, ) – Lazily iterate the range, replacing each number with the characters of its string representation, and returning a new lazy sequence. The | keeps the new sequence flattened.
  3. [$_] – Take the element at the index defined by the (implicitly declared) lambda parameter $_.
  4. + – Coerce it to a number. (This step is needed because coercing a string directly to a boolean always gives True unless the string is empty.)
  5. ! – Coerce it to a boolean and negate it.

(try it online)

EDIT: -1 byte thanks to b2gills.

smls

Posted 2016-08-28T13:09:50.367

Reputation: 4 352

You can shorten yours to {!+map(|*.comb,0..*)[$_]} I came up with {!+({|($++).comb}...*)[$_]} before looking to see if there was already a P6 answer. !+ can be replaced by 1> – Brad Gilbert b2gills – 2016-08-28T16:41:39.280

4

Python 3.5, 40 bytes

lambda n:('%d'*-~n%(*range(n),n))[n]<'1'

Test it on repl.it.

How it works

For input n, '%d'*-~n repeats the format string n + 1 times.

(*range(n),n) unpacks the range [0, ..., n - 1] and yields the tuple (0, ..., n).

...%... replaces each occurrence of %d with the corresponding integer in the range, yielding the string 01234567891011...n.

(...)[n]<'1' selects the character at index n and tests if it is less than the character 1.

Dennis

Posted 2016-08-28T13:09:50.367

Reputation: 196 637

4

Jelly, 6 bytes

RDF⁸ị¬

Try it online! or verify all test cases.

How it works

RDF⁸ị¬  Main link. Argument: n

R       Range; yield [1, ..., n].
 D      Decimal; convert all integers in that range to base 10 arrays.
  F     Flatten the result.
   ⁸ị   Extract the digit at index n (1-based).
        This returns 0 if the array is empty (n = 0).
     ¬  Logical NOT; return 1 if the digit is 0, 0 if not.

Dennis

Posted 2016-08-28T13:09:50.367

Reputation: 196 637

3

Python 3, 44 bytes

lambda n:''.join(map(str,range(n+1)))[n]<'1'

An anonymous function that takes input via argument and returns True or False as appropriate.

How it works

lambda n      Anonymous function with input n
range(n+1)    Yield the range [0, n]...
map(str,...)  ...convert all elements to string...
''.join(..)   ...concatenate...
...[n]        ...yield nth character...
:...<'1'      ...return True if int(character)==0 else return False

Try it on Ideone

TheBikingViking

Posted 2016-08-28T13:09:50.367

Reputation: 3 674

3

Pyth, 8 7 bytes

Thanks to @LeakyNun for -1 byte

!s@jkUh

This is my first attempt at golfing in Pyth.

A full program that prints True or False as appropriate.

Try it online

First 25 truthy inputs

How it works

!s@jkUh    Program. Input: Q
      hQ   Head. Yield Q+1
     U     Unary range. Yield [0, Q]
   jk      Join. Join on empty string
  @     Q  Index. Yield string[Q]
 s         Integer. Convert to integer
!          Logical negation. 0 -> True, all other digits -> False
           Print. Print result implicitly

TheBikingViking

Posted 2016-08-28T13:09:50.367

Reputation: 3 674

3

S.I.L.O.S, 141 bytes

readIO
i+1
lblL
c=C
p=1
lblc
p*10
c/10
if c c
p/10
lbln
m=C
m/p
m%10
p/10
i-1
if i C
GOTO H
lblC
if p n
C+1
GOTO L
lblH
m/m
m-1
m|
printInt m

Try it online!

Uses only 5 integers, maximum memory efficiency \o/

Explanation

We generate as many digits as the input in the Champernowne's constant.

In the main loop, we do the following:

  • Find the length of the current number by floor_dividing it by 10 repeatedly until it reaches 0, and then count the number of divisions used.
  • Instead of storing the number of divisions, we store 10 to that number power instead.
  • Iterate through each digit as such: the 100s digit of 1234 is obtained by (1234/10)%10 where / is floor division.
  • For each digit generated, take 1 from the input, while checking if the input reached zero.
  • If the input reaches zero, check if the current digit is 0 and then halts.

Leaky Nun

Posted 2016-08-28T13:09:50.367

Reputation: 45 011

3

JavaScript (ES6), 45 bytes + Kudos

f=(n,s='0')=>s[n]?!+s[n]:f(n-s.length,-~s+'')

My best non-Kudos version was 34 bytes:

n=>!+(g=s=>s[n]||g(s+i++))('',i=0)

Neil

Posted 2016-08-28T13:09:50.367

Reputation: 95 035

1I thought kudos was a library until I realized there was a kudos on the challenge :P – Conor O'Brien – 2016-08-28T19:13:22.493

1

JavaScript (ES6), 47 bytes

n=>[...Array(n+1)].reduce((a,_,i)=>a+i,'')[n]<1

c.P.u1

Posted 2016-08-28T13:09:50.367

Reputation: 1 049

1

Javascript (ES6), 42 33 bytes

n=>!+(r=i=>i>n?'':i+r(i+1))(0)[n]

Example:

let f =
n=>!+(r=i=>i>n?'':i+r(i+1))(0)[n]

// test all integers in [0, 312]
for(var n = 0, list = []; n <= 312; n++) {
  f(n) && list.push(n);
}
console.log(list.join(','));

Arnauld

Posted 2016-08-28T13:09:50.367

Reputation: 111 334

1

Groovy, 56 bytes

def f(n){def s=''<<'';(0..n).each{s<<it};!(s[n] as int)}

Nothing fancy, but I'm trying out some new things.

def f(n) {
  def s = ''<<''           // declare a StringBuffer
  (0..n).each { s << it }
  !(s[n] as int)           // Groovy considers a non-null char truthy, so we have to cast 
}

lealand

Posted 2016-08-28T13:09:50.367

Reputation: 131

1

Perl, 24 bytes

Includes +1 for -p

Run with input on STDIN:

zero.pl <<< 31

print 1 for zero, nothing otherwise

zero.pl

$_=!(map/./g,0..$_)[$_]

Ton Hospel

Posted 2016-08-28T13:09:50.367

Reputation: 14 114

1

Ruby, 35 23 bytes

This is an anonymous function that concatenates [0..n], takes the nth index and checks if that char is "0" (less than "1"). Golfing suggestions welcome.

->n{([*0..n]*'')[n]<?1}

Ungolfing

->n{...}   # Create an anonymous function with parameter n.
[*0..n]    # Create an array of the range [0..n].
[...]*''   # Join the array using the empty string.
(...)[n]   # Take the char at the n-th index of the string.
<?1        # Check if the char is < "1" (that is, "0").

Sherlock9

Posted 2016-08-28T13:09:50.367

Reputation: 11 664

1

Actually, 9 8 bytes

This answer concatenates the range [0..n], takes the nth index and checks if that char is "0". Golfing suggestions welcome. Try it online!

;urεjE≈Y

Ungolfing

;          Duplicate n
 ur        Increment the duplicate and create range [0..n].
   εj      Join the range with an empty string. Stack: <string> n
     E     Take the char at the n-th index.
      ≈    int(a)
       Y   Logical NOT. If the digit is 0, then return 1, else return 0.

Sherlock9

Posted 2016-08-28T13:09:50.367

Reputation: 11 664

1

PHP, 36 bytes

<?=!join(range(0,$a=$argv[1]))[$a];

Print 1 if Champernowne argument-th decimal is 0, else print '' (empty string).

Crypto

Posted 2016-08-28T13:09:50.367

Reputation: 862

1

R, 61 57 bytes

Thanks to @plannapus for 4 bytes.

n=scan();strsplit(paste(0:n,collapse=""),"")[[1]][n+1]==0

Creates a vector of numbers 0:n (for 0 indexing), creates a string of them, pulls the nth value from string (adjusting for 0 indexing). Converts to numeric and tests if it is 0.

user5957401

Posted 2016-08-28T13:09:50.367

Reputation: 699

1

Bash, 31 28 bytes

seq -s "" 0 $1|egrep ^.{$1}0

Output is non-empty (truthy) or empty (falsy). Test it on Ideone.

Dennis

Posted 2016-08-28T13:09:50.367

Reputation: 196 637

1

Julia, 21 20 bytes

!n=join(0:n)[n+1]<49

Thanks to @LuisMendo for golfing off 1 byte!

Try it online!

Dennis

Posted 2016-08-28T13:09:50.367

Reputation: 196 637

0

GolfScript, 12 bytes

~.),""*\=48=

Explanation:

~             Evaluate the input.
 .            Duplicate it
  )           Increment the duplicate.
   ,          Create an array from 0 to it.
    ""*       Join it with an empty string.
       \=     Get the n-th index of this string, where n is the input
         48=  Is it equal to 0?

Try it online or verify all test cases!

Loovjo

Posted 2016-08-28T13:09:50.367

Reputation: 7 357

0

Javascript (ES5): 61 60 bytes

function(b){for(s="";s.length<b;)s+=s.length;return 0==s[b]}

Ungolfed:

function a(b){
  for(var s="";s.length<b;)
    s+=s.length;
  }
  return (s[b]==0);
}

Old:

function(n){s="";while(s.length<n)s+=s.length;return s[n]==0}

Ungolfed old:

function a(n){
  var str="";
  while(str.length<n)str+=str.length; //Create String as long as needed
  return str[n]==0 //Check for 0 and return
}

Paul Schmitz

Posted 2016-08-28T13:09:50.367

Reputation: 1 089

How about !s[n] instead of s[n]==0? – Conor O'Brien – 2016-08-28T17:54:07.997

@ConorO'Brien Does not work for me. My function a returns a(31)=true, while yours (function(n){s="";while(s.length<n)s+=s.length;return !s[n]}) returns a(31)=false. – Paul Schmitz – 2016-08-28T17:58:53.193

hm. my mistake. – Conor O'Brien – 2016-08-28T18:05:03.293

0

C, 154 bytes

s(n,v,k,z){for(k=1;(z=n%10,n/=10)&&!v||k<v;++k); return v?z:k;}
f(n,i,j,c){for(i=0,j=0;;++i){c=s(i,0,0,0);j+=c;if(j>n){c=s(i,j-n,c,0);break;}}return !c;}

the function that calculate the value is f(n,0,0,0) where n is the input index. it can calculate from index changing "return !c" in "return c" the value of the array in that index... i don't understand how but it seems to work ok....

main()
{int   i,r;
 char  a[]="0123456789101112131415161718192021222324252627282930313233343536";

 for(i=0; i<1000; ++i) 
    if(r=f(i,0,0,0))  
        printf("%u|",i);
}
/*
 154
 0|11|31|51|71|91|111|131|151|171|191|192|194|197|200|203|206|209|212|215|218|222
|252|282|312|342|372|402|432|462|491|492|494|497|500|503|506|509|512|515|518|522|552
|582|612|642|672|702|732|762|791|792|794|797|800|803|806|809|812|815|818|822|852
|882|912|942|972|
*/

RosLuP

Posted 2016-08-28T13:09:50.367

Reputation: 3 036

0

CoffeeScript, 56 bytes

a=(b)->
 s=""
 while s.length<b #loop for building string with required length
  s+=s.length     #add number
 "0"==s[b]        #return, if the number at the position equals zero

Paul Schmitz

Posted 2016-08-28T13:09:50.367

Reputation: 1 089

0

zsh, 31 bytes

exit ${${(j..):-{0..$1}}[$1+1]}

exit 0 is true in zsh

izabera

Posted 2016-08-28T13:09:50.367

Reputation: 879

0

C#, 71 bytes

And I thought it was short at first, but then I had to add n+=11 to prevent it from throwing a System.IndexOutOfRangeException when numbers below 11 were input

return String.Join("",Enumerable.Range(0,n+=11).ToArray())[n]=='0'?1:0;

Daniel

Posted 2016-08-28T13:09:50.367

Reputation: 1 808

0

Pyke, 7 bytes

m`sQ@b!

Try it here!

Blue

Posted 2016-08-28T13:09:50.367

Reputation: 26 661

0

PowerShell v2+, 32 bytes

param($n)(-join(0..$n))[$n]-eq48

Does the same as other answers -- takes the range from 0 to input $n, -joins together into a string, takes the [$n] index, checks if it's -equal to 48 (i.e., ASCII for 0).

Note this will only work up to input 49999, as the PowerShell range operator .. only supports ranges of 50,000 elements or fewer. For larger inputs, you'll need to use the following, based on my previous Champernowne answer, at 58 bytes:

param($n)$j=$n;for($c='';$j-ge0;$j--){$c+=$i++}$c[$n]-eq48

AdmBorkBork

Posted 2016-08-28T13:09:50.367

Reputation: 41 581

0

Octave, 41 29 bytes

Credit to Dennis, whose Julia answer made me realize I wasn't treating input 0 correctly.

@(n)sprintf('%i',0:n)(n+1)<49

This is an anonymous function.

Try at Ideone.

Explanation

For input n, this generates the Champernowne digits corresponding to the first n+1 numbers starting at 0 (which is more than enough). sprintf is used for this so that no blank spaces appear. The result is true if the n+1-th digit (1-based) is zero, that is, if its ASCII code is less than 49.

Luis Mendo

Posted 2016-08-28T13:09:50.367

Reputation: 87 464

0

R, 57 bytes

grepl("0$",substr(paste(0:(n=scan()),collapse=""),1,n+1))

Build a string corresponding to 0:n, keeps the first n+1 characters and check if the last character is a zero.

plannapus

Posted 2016-08-28T13:09:50.367

Reputation: 8 610