35
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ What's the highest position we need to work for? Eg, will the number ever be 987654321123456877654234354675. \$\endgroup\$ – Morgan Thrapp Dec 17 '15 at 15:08
  • \$\begingroup\$ @MorganThrapp I'll probably test integers in the range 0 <= x <= 99, but it should theoretically work for integers higher than 99. \$\endgroup\$ – Adnan Dec 17 '15 at 15:12
  • 2
    \$\begingroup\$ Obligatory OEIS \$\endgroup\$ – Leaky Nun Aug 12 '16 at 4:53

28 Answers 28

8
\$\begingroup\$

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

\$\endgroup\$
10
\$\begingroup\$

LabVIEW, 29 LabVIEW Primitives

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

\$\endgroup\$
6
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Oh wow such good \$\endgroup\$ – user45510 Dec 17 '15 at 18:31
  • \$\begingroup\$ I think you can move the y= part to the y=b=" "; incrementing a space is like incrementing zero. (a=prompt(y=b=" ");...) \$\endgroup\$ – Conor O'Brien Dec 17 '15 at 21:34
  • 1
    \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ Nice find. \$\endgroup\$ – SuperJedi224 Dec 17 '15 at 21:39
4
\$\begingroup\$

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.

\$\endgroup\$
4
\$\begingroup\$

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.

\$\endgroup\$
4
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ Why does your "How it works" section contains a q in the code and not the logical negation symbol ¬? \$\endgroup\$ – Fatalize Dec 18 '15 at 10:38
  • \$\begingroup\$ @Fatalize ¬ is a shortcut for (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. \$\endgroup\$ – ETHproductions Dec 18 '15 at 15:32
3
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – Rɪᴋᴇʀ Dec 17 '15 at 21:31
  • \$\begingroup\$ Yeah, start and end for the first occurrence. \$\endgroup\$ – Nikolai97 Dec 17 '15 at 21:32
3
\$\begingroup\$

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

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

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

\$\endgroup\$
  • 1
    \$\begingroup\$ Clever way of doing it. Frustrating that .IndexOf() apparently has higher operating preference than unary -join forcing the parens and quotes. :-/ \$\endgroup\$ – AdmBorkBork Dec 18 '15 at 14:09
3
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ I don't think this handles 0 :( \$\endgroup\$ – David Dec 18 '15 at 6:40
  • \$\begingroup\$ @David Now it does. Thanks for noticing! It only cost 3 bytes :-) \$\endgroup\$ – Luis Mendo Dec 18 '15 at 10:36
  • \$\begingroup\$ 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. \$\endgroup\$ – Giuseppe Mar 21 '18 at 17:21
  • \$\begingroup\$ @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) \$\endgroup\$ – Luis Mendo Mar 21 '18 at 17:41
  • \$\begingroup\$ 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! \$\endgroup\$ – Giuseppe Mar 21 '18 at 17:56
2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ 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). \$\endgroup\$ – TessellatingHeckler Dec 18 '15 at 7:39
  • 1
    \$\begingroup\$ @TessellatingHeckler Nice way to rewrite the loop - thanks! I moved the $c concatenation into the loop to golf a semicolon. Now at 50. \$\endgroup\$ – AdmBorkBork Dec 18 '15 at 14:14
2
\$\begingroup\$

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.

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

Python 3, 54.

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

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.

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

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

𝔼𝕊𝕄𝕚𝕟, 13 chars / 22 bytes

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

Try it here (Firefox only).

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

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

Mathematica, 101 bytes

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

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.

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

05AB1E, 6 bytes (non-competing)

nLJsk>

Try it online!

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

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>

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

Jelly, 5 bytes

+⁵RVw

Try it online!

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

Stax, 6 bytes

⌐╛∙#»▓

Run and debug it

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

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

\$\endgroup\$
0
\$\begingroup\$

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

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

\$\endgroup\$
0
\$\begingroup\$

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

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