Find the number in the Champernowne constant

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

• What's the highest position we need to work for? Eg, will the number ever be 987654321123456877654234354675. Dec 17, 2015 at 15:08
• @MorganThrapp I'll probably test integers in the range 0 <= x <= 99, but it should theoretically work for integers higher than 99. Dec 17, 2015 at 15:12
• Obligatory OEIS Aug 12, 2016 at 4:53

LabVIEW, 29 LabVIEW Primitives

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

Pyth, 10

hxjkS+QTQ


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

Test Suite

• I think implicit input was implemented before 2015-12-17 15:01:23Z or something? Aug 4, 2017 at 11:07
• @EriktheOutgolfer It was added in 2016: github.com/isaacg1/pyth/commit/… Aug 4, 2017 at 14:07

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.

• I think you can move the y= part to the y=b=" "; incrementing a space is like incrementing zero. (a=prompt(y=b=" ");...) Dec 17, 2015 at 21:34
• @CᴏɴᴏʀO'Bʀɪᴇɴ Nice find. Dec 17, 2015 at 21:39

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.

• I don't think you need the .show Aug 4, 2017 at 0:58
• And some friendly competition. albeit two years late. Aug 4, 2017 at 1:00

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.

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

• Why does your "How it works" section contains a q in the code and not the logical negation symbol ¬? Dec 18, 2015 at 10:38
• @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. Dec 18, 2015 at 15:32

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.

• Do 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. Dec 17, 2015 at 21:31
• Yeah, start and end for the first occurrence. Dec 17, 2015 at 21:32

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

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

• Clever way of doing it. Frustrating that .IndexOf() apparently has higher operating preference than unary -join forcing the parens and quotes. :-/ Dec 18, 2015 at 14:09

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  • I don't think this handles 0 :( Dec 18, 2015 at 6:40 • @David Now it does. Thanks for noticing! It only cost 3 bytes :-) Dec 18, 2015 at 10:36 • 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. Mar 21, 2018 at 17:21 • @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) Mar 21, 2018 at 17:41 • 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! Mar 21, 2018 at 17:56 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. • 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). Dec 18, 2015 at 7:39
• @TessellatingHeckler Nice way to rewrite the loop - thanks! I moved the $c concatenation into the loop to golf a semicolon. Now at 50. Dec 18, 2015 at 14:14 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. Python 3, 54. print(''.join(map(str,range(1,9**7))).find(input())+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. 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


𝔼𝕊𝕄𝕚𝕟, 13 chars / 22 bytes

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


Try it here (Firefox only).

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


Mathematica, 101 bytes

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


Haskell, 8273 55 bytes

Migrated from the duplicate

05AB1E, 6 bytes (non-competing)

nLJsk>


Try it online!

JavaScript (ES6), 5039 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>

Jelly, 5 bytes

+⁵RVw


Try it online!

Stax, 6 bytes

⌐╛∙#»▓


Run and debug it

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

Husk, 6 5 bytes

€ṁdNd


Try it online!

-1 thanks to Razetime

€        The 1-based index, in
d      decimal digits
ṁ       concat-mapped over
N     all natural numbers,
d    of the decimal digits of the input.

• -1 Nov 13, 2020 at 16:24
• @Razetime Knew how you did it before I clicked the link! Nov 13, 2020 at 16:28

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


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

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
`