Find the number in the Champernowne constant

35

2

Introduction

In base 10, the Champernowne constant is defined by concatenating representations of successive integers. In base 10: 0.1234567891011121314151617... and so on.

You can see that the first appearence of 15 starts at the 20th decimal:

  Position
  0000000001111111111222222222233333333334444444444555555555566666666
  1234567890123456789012345678901234567890123456789012345678901234567
                     ^
0.1234567891011121314151617181920212223242526272829303132333435363738...
                     ^^
                     15 = position 20

The first appearence of 45 starts at the 4th decimal:

  Position
  0000000001111111111222222222233333333334444444444555555555566666666
  1234567890123456789012345678901234567890123456789012345678901234567
     ^               
0.1234567891011121314151617181920212223242526272829303132333435363738...
     ^^
     45 = position 4

So, the task is easy. Given a non-negative integer, output the position of the integer in the Champernowne constant.

Rules

  • You may provide a function or a program
  • This is , so the submission with the least amount of bytes wins!

Test cases

Input: 20
Output: 30

Input: 333
Output: 56

Input: 0
Output: 11 (note that the 0 before the decimal point is ignored)

Input: 2930
Output: 48

Adnan

Posted 2015-12-17T15:01:23.573

Reputation: 41 965

What's the highest position we need to work for? Eg, will the number ever be 987654321123456877654234354675. – Morgan Thrapp – 2015-12-17T15:08:34.097

@MorganThrapp I'll probably test integers in the range 0 <= x <= 99, but it should theoretically work for integers higher than 99. – Adnan – 2015-12-17T15:12:23.850

2Obligatory OEIS – Leaky Nun – 2016-08-12T04:53:13.223

Answers

8

Pyth, 10

hxjkS+QT`Q

Concatenates first input + 10 numbers then finds the 0 based index plus one.. The extra ten are only needed for 0.

Test Suite

FryAmTheEggman

Posted 2015-12-17T15:01:23.573

Reputation: 16 206

I think implicit input was implemented before 2015-12-17 15:01:23Z or something? – Erik the Outgolfer – 2017-08-04T11:07:56.957

@EriktheOutgolfer It was added in 2016: https://github.com/isaacg1/pyth/commit/3f7cbe42d143eeeb7eb1633bdf3d5a7fdb348007

– FryAmTheEggman – 2017-08-04T14:07:35.423

10

LabVIEW, 29 LabVIEW Primitives

This uses strings for now. It matches the input as a pattern and outputs the offset - (input lenght -1).

Eumel

Posted 2015-12-17T15:01:23.573

Reputation: 2 487

6

Javascript, 57 bytes

a=prompt();for(y=b=" ";y<a+11;)b+=++y;alert(b.indexOf(a))

Saved 1 byte thanks to Conor O'Brien.

SuperJedi224

Posted 2015-12-17T15:01:23.573

Reputation: 11 342

I think you can move the y= part to the y=b=" "; incrementing a space is like incrementing zero. (a=prompt(y=b=" ");...) – Conor O'Brien – 2015-12-17T21:34:41.547

1@CᴏɴᴏʀO'Bʀɪᴇɴ Nice find. – SuperJedi224 – 2015-12-17T21:39:53.763

4

Japt, 11 bytes

This was originally beating Pyth, but apparently it didn't work for input 0.

1+1oU+B ¬bU

Try it online!

How it works

1+1oU+B ¬ bU
1+1oU+B q bU  // Implicit: U = input integer
  1oU+B       // Generate the range [0, U+11).
        q bU  // Join and take the index of U.
1+            // Add one to get the correct result.
              // Implicit: output last expression

ETHproductions

Posted 2015-12-17T15:01:23.573

Reputation: 47 880

Why does your "How it works" section contains a q in the code and not the logical negation symbol ¬? – Fatalize – 2015-12-18T10:38:39.553

@Fatalize ¬ is a shortcut for q (that's q with a following space). This seems to often be a point of confusion, so I've lined up the shorter version with the full one. – ETHproductions – 2015-12-18T15:32:10.640

4

Haskell, 62 bytes

a#b|and$zipWith(==)a b=1|1<2=1+a#tail b 
(#(show=<<[1..])).show

Usage example: (#(show=<<[1..])).show $ 2930-> 48.

How it works: a # b finds the position of a within b: if a is prefix of b return 1, else add 1to a recursive call with a # tail b. The pointfree function (#(show=<<[1..])).show expects an (unnamed) argument n and calls show n # show=<<[1..].

The function subIndex would also do the job of #, but the required import Data.List.Utils doesn't pay off.

nimi

Posted 2015-12-17T15:01:23.573

Reputation: 34 639

I don't think you need the .show – Post Rock Garf Hunter – 2017-08-04T00:58:16.193

And some friendly competition. albeit two years late. – Post Rock Garf Hunter – 2017-08-04T01:00:41.013

4

Ruby, 28

->n{[*0..n+10]*''=~/\B#{n}/}

Includes a 0 at the beginning so that matches are 1-indexed, but uses \B to require that the match not be at the beginning of the string.

histocrat

Posted 2015-12-17T15:01:23.573

Reputation: 20 600

3

Lua, 54 Bytes

s=""for i=1,1e4 do s=s..i end print(s:find(io.read()))

Note: Currently this program prints both the first occurrence of the first char of the string, and the point where it ends. If this is not allowed, it will cost a few more bytes. I would like to petition for a bonus because my program prints out both the first position and last position of the input number.

Nikolai97

Posted 2015-12-17T15:01:23.573

Reputation: 653

1Do you mean the start indices and end indices for the first occurence of the number? Because theoretically the number would be in there an infinite amount of times. – Rɪᴋᴇʀ – 2015-12-17T21:31:31.417

Yeah, start and end for the first occurrence. – Nikolai97 – 2015-12-17T21:32:33.007

3

MATL (release 1.0.1), 22 bytes

iXK10+:"@Ys]N$hKYsXf1)

Example

>> matl iXK10+:"@Ys]N$hKYsXf1)
> 333
56

Explanation

i       % Input
XK      % Copy to clipboard K            
10+     % Add 10. This is needed in case input is 0
:       % Vector of equally spaced values, starting from 1
"       % For each
  @Ys   %   For loop variable as a string
]       % End                            
N$h     % Horizontal concatenation of all stack contents
KYs     % Paste from clipboard K (input number) and convert to string
Xf      % Find one string within another 
1)      % First value

MATL (release 20.8.0), 16 bytes (language postdates challenge)

Credit to @Giuseppe for this version of the program (slightly modified)

10+:"@V]&hGVXf1)

Try it online!

Explanation

10+     % Implicit Input. Add 10. This is needed in case input is 0 
:       % Vector of equally spaced values, starting from 1
"       % For each
  @V    %   For loop variable as a string 
]       % End
&h      % Horizontal concatenation of all stack contents
GV      % Paste from automatic clipboard G (input number) and convert to string
Xf      % Find one string within another 
1)      % First value

Luis Mendo

Posted 2015-12-17T15:01:23.573

Reputation: 87 464

I don't think this handles 0 :( – David – 2015-12-18T06:40:46.943

@David Now it does. Thanks for noticing! It only cost 3 bytes :-) – Luis Mendo – 2015-12-18T10:36:38.740

now that clipboard G contains the input (and implicit input), I guess this answer can be shortened by quite a lot, and all the Ys need to change to V anyway; I came up with 10+:"@Vv]!GVXf1) for 16 bytes. – Giuseppe – 2018-03-21T17:21:35.973

@Giuseppe Thanks for the heads-up! Updated, with due credit (and with a "language postdates challange" note; I'm not a big fan of the new rule)

– Luis Mendo – 2018-03-21T17:41:10.400

I don't mind that rule so much (the flags one drives me crazy, though); I was mostly commenting here since I noticed that Ys needed to change to V to use in the most up-to-date version of the interpreter. I'm always impressed with how much the language has improved!

– Giuseppe – 2018-03-21T17:56:21.987

@Giuseppe Thanks! Yes, I'm not a big fan of that other rule either... – Luis Mendo – 2018-03-21T18:07:49.123

3

MATL, 22 bytes

it10+:Yst' '=~)wYsXf1)

Take the input (i), make the vector 1 to input+10 (10+:), converts the vector to a string (Ys), and remove the spaces, which is painful, (t' '=~)). Then, convert the input to a string (Ys), find where the input string is in the string of numbers (Xf) and take the first location (1)). The t's and w's are manipulating the stack (duplicate and swap, respectively).

David

Posted 2015-12-17T15:01:23.573

Reputation: 1 316

3

PowerShell, 39 44 bytes

[Edit: my assumption doesn't hold, building an array from 1-0 doesn't find 0 at place 11. Instead, build from 1-x+10 to handle 0 as well, now 44 bytes]

param($i)(1..($i+10)-join'').IndexOf("$i")+1

You will always find x when building a string of the Champernowne constant at the latest point when you add x onto the end, so an array from 1-x will always have the answer in it. The question becomes "does it occur any sooner than that?". This code

param($i)(1..$i-join'').IndexOf("$i")+1

e.g.

PS C:\Temp> .\Champer.ps1 20
30

generates a range of numbers, casts it to a string, and searches for the parameter inside it. Because PowerShell is an object oriented shell, the parameter is actually an [int] type, so trying to save two characters with .IndexOf($i) would search the string for an integer and find nothing. That's why I use string interpolation "$i".

TessellatingHeckler

Posted 2015-12-17T15:01:23.573

Reputation: 2 412

1Clever way of doing it. Frustrating that .IndexOf() apparently has higher operating preference than unary -join forcing the parens and quotes. :-/ – AdmBorkBork – 2015-12-18T14:09:50.583

2

PowerShell, 54 50 Bytes

for($c='';!($x=$c.IndexOf("$args")+1)){$c+=++$i}$x

Thanks to TessellatingHeckler for the idea of swapping the while loop for a for loop.

Executes via a for loop. As with other languages, the first statement in the loop can construct variables and assignments, so this starts with $c equal to just the empty string '' so that we have zero-indexing of the string lining up with the decimal indexing of the challenge. We're then in a loop that checks whether $c has the input integer ($args) somewhere within it (i.e., since .IndexOf() returns -1 if the string isn't found, we add one to that (0) and not it ($TRUE) to continue the loop). If it's not found, we add on our pre-incremented $i counter variable, then recheck the string. Once the string is found, .IndexOf() will return a positive value, the not of which will be $FALSE, breaking out of the loop. Finally, we output the index with $x.

AdmBorkBork

Posted 2015-12-17T15:01:23.573

Reputation: 41 581

Ideal for a classic for loop... for($c='.';($x=$c.IndexOf("$args"))-lt0;$c+=++$i){}$x and save 1 character. Since most of the IndexOf calls will return -1, add one to it and boolean ! cast it, for a shorter test. But you need parens to do that. Empty $c and +1 inside existing parens, bonus it's shorter. for($c='';!($x=$c.IndexOf("$args")+1);$c+=++$i){}$x 51 bytes. (but I posted my 39 byte one as its own answer because it's a completely different approach :P). – TessellatingHeckler – 2015-12-18T07:39:40.387

1@TessellatingHeckler Nice way to rewrite the loop - thanks! I moved the $c concatenation into the loop to golf a semicolon. Now at 50. – AdmBorkBork – 2015-12-18T14:14:46.993

2

JavaScript (ES6), 40 bytes

x=>(f=n=>n?f(n-1)+n:" ")(x+11).search(x)

Uses the recursive function f to avoid loops. The search method works the same as indexOf except that it takes a RegExp as a parameter, which is irrelevant for this challenge.

Adding a " " for the n=0 case (zero is falsy in JS) coerces the + to perform string concatenation instead of addition, and corrects for zero-based indexing.

intrepidcoder

Posted 2015-12-17T15:01:23.573

Reputation: 2 575

1

Mathematica, 101 bytes

(If[#==0,11,m=Min@SequencePosition[s=Flatten[(K=IntegerDigits)/@Range[0,#]],K@#];Length@s[[;;m-1]]])&

J42161217

Posted 2015-12-17T15:01:23.573

Reputation: 15 931

1

Haskell, 82 73 55 bytes

Migrated from the duplicate

x!b|or$zipWith(==)x b=0
x!(_:b)=1+x!b
(!(show=<<[1..]))

Try it online!

Explanation

First we define !. x!b truncates b to the first appearance of x. It does this by checking if b starts with x (or$zipWith(==)x b) returning x if it does and moving one down the string otherwise. Then we define our main function. Our main function is a point-free function that takes the constant (show=<<[1..]) and truncates it to the first appearance of x. This takes x as a string.

Post Rock Garf Hunter

Posted 2015-12-17T15:01:23.573

Reputation: 55 382

1

Jelly, 5 bytes

+⁵RVw

Try it online!

Erik the Outgolfer

Posted 2015-12-17T15:01:23.573

Reputation: 38 134

1

JavaScript (ES6), 50 39 38 bytes

x=s=``
f=n=>-~s.search(n)||f(n,s+=++x)

Try it

x=s=``
f=n=>-~s.search(n)||f(n,s+=++x)
o.innerText=f(i.value=15);oninput=_=>o.innerText=f(+i.value)
<input id=i type=number><pre id=o></pre>

Shaggy

Posted 2015-12-17T15:01:23.573

Reputation: 24 623

1

05AB1E, 6 bytes (non-competing)

nLJsk>

Try it online!

Magic Octopus Urn

Posted 2015-12-17T15:01:23.573

Reputation: 19 422

1

Stax, 6 bytes

⌐╛∙#»▓

Run and debug it

recursive

Posted 2015-12-17T15:01:23.573

Reputation: 8 616

1

Perl 6, 26 bytes

{[~](0..$_).index($_)||11}

Try it online!

Finds the index of the element in the concatenated range from 0 to that element, or 11 if the number is a zero

Jo King

Posted 2015-12-17T15:01:23.573

Reputation: 38 234

1

Python 3, 54.

print(''.join(map(str,range(1,9**7))).find(input())+1)

Morgan Thrapp

Posted 2015-12-17T15:01:23.573

Reputation: 3 574

1

CJam, 11 bytes

r_i),s\#Be|

Test it here.

I'm finding the position of N in the string 01234...N to account for the 1-based indexing. Finally I fix 0 by applying logical OR with 11.

Martin Ender

Posted 2015-12-17T15:01:23.573

Reputation: 184 808

1

Seriously, 13 bytes

;≈9u+R`$`MΣí

Takes input as an integer. Contains unprintables, so hexdump:

0c3bf739752b526024604de4a1

Try it online

Explanation:

;≈9u+R`$`MΣí
<form feed>   push str(input)
;≈9u+R        dupe, push [1,...,input+10]
      `$`MΣ   string concatenation of list
           í  get index of input

Mego

Posted 2015-12-17T15:01:23.573

Reputation: 32 998

1

, 13 chars / 22 bytes

1+⩥(1,ï+ḋ)⨝ÿï

Try it here (Firefox only).

Mama Fun Roll

Posted 2015-12-17T15:01:23.573

Reputation: 7 234

1

k4, 21 bytes

{*1+(,/$1+!10+x)ss$x}

Same algo as everyone else—concatenate [1..10+x] as strings, search for x as string, convert to one-based indexing, return first hit.

Checking the test cases:

  &/20 4 30 56 11 48={*1+(,/$1+!10+x)ss$x}'15 45 20 333 0 2930
1b

Aaron Davies

Posted 2015-12-17T15:01:23.573

Reputation: 881

0

Perl 5, 42 + 1 (-p) = 43 bytes

(join'',0..$_+10)=~/^(0.*?)$_/;$_=length$1

Try it online!

Explanation

(join'',0..$_+10)   #concatenate all of the numbers from 0 to 10 over the input
=~/^(0.*?)$_/;      #skip the first 0, then find the input
$_=length$1         #the length of the string preceding the input is the answer

Xcali

Posted 2015-12-17T15:01:23.573

Reputation: 7 671

0

Perl 6/Rakudo 29 bytes

{$_~=$++until /(.+)$^a/;$0.chars}

Defines a function with one input ($^a). Call thus:

say {$_~=$++until /(.+)$^a/;$0.chars}(333)
> 56

Appending $, an anonymous variable, incrementing $++ until the input $^a is found, and then counting the number of chars before it. Requiring at least 1 char before it .+ in the regex usefully excludes the 0->0 case

Phil H

Posted 2015-12-17T15:01:23.573

Reputation: 1 376

0

J, 30 Bytes

{.I.(":E.[:}.' '-.~":@i.@+&11)

Could probably be golfed down a bit more, specifically in concatenating the first n+10 integers.

Explanation:

{.I.(":E.[:}.' '-.~":@i.@+&11)
                      i.@+&11   | Integers 0 to n+10
                   ":@          | Format list to string
             ' '-.~             | Strip spaces
           }.                   | Behead (remove leading 0)
         [:                     | Cap (previous verbs executed in order, not as a fork)
     ":E.                       | Find matches to the string n (returns a boolean vector)
  I.                            | Indexes of 1s
{.                              | Take only the first

Note that this is 0-indexed. Examples:

    {.I.(":E.[:}.' '-.~":@i.@+&11) 1
0
    {.I.(":E.[:}.' '-.~":@i.@+&11) 0
10
    {.I.(":E.[:}.' '-.~":@i.@+&11) 333
55

Bolce Bussiere

Posted 2015-12-17T15:01:23.573

Reputation: 970

0

Husk, 6 bytes

€ΣmdNd

Try it online!

€         The 1-based index in
 Σ        the list of concatenated
   d      decimal digits
  m N     of every natural number
     d    of the decimal digits of
          the input.

Unrelated String

Posted 2015-12-17T15:01:23.573

Reputation: 5 300