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 code-golf, 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
29 Answers 29
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+QT`Q
Concatenates first input + 10 numbers then finds the 0 based index plus one.. The extra ten are only needed for 0.
-
\$\begingroup\$ I think implicit input was implemented before
2015年12月17日 15:01:23Zor something? \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年08月04日 11:07:56 +00:00Commented Aug 4, 2017 at 11:07 -
\$\begingroup\$ @EriktheOutgolfer It was added in 2016: github.com/isaacg1/pyth/commit/… \$\endgroup\$FryAmTheEggman– FryAmTheEggman2017年08月04日 14:07:35 +00:00Commented 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.
-
\$\begingroup\$ I think you can move the
y=part to they=b=" "; incrementing a space is like incrementing zero. (a=prompt(y=b=" ");...) \$\endgroup\$Conor O'Brien– Conor O'Brien2015年12月17日 21:34:41 +00:00Commented Dec 17, 2015 at 21:34 -
1\$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ Nice find. \$\endgroup\$SuperJedi224– SuperJedi2242015年12月17日 21:39:53 +00:00Commented 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.
-
\$\begingroup\$ I don't think you need the
.show\$\endgroup\$2017年08月04日 00:58:16 +00:00Commented Aug 4, 2017 at 0:58 -
\$\begingroup\$ And some friendly competition. albeit two years late. \$\endgroup\$2017年08月04日 01:00:41 +00:00Commented 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
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
-
\$\begingroup\$ Why does your "How it works" section contains a
qin the code and not the logical negation symbol¬? \$\endgroup\$Fatalize– Fatalize2015年12月18日 10:38:39 +00:00Commented Dec 18, 2015 at 10:38 -
\$\begingroup\$ @Fatalize
¬is a shortcut forq(that'sqwith 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– ETHproductions2015年12月18日 15:32:10 +00:00Commented 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.
-
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\$Riker– Riker2015年12月17日 21:31:31 +00:00Commented Dec 17, 2015 at 21:31
-
\$\begingroup\$ Yeah, start and end for the first occurrence. \$\endgroup\$Nikolai97– Nikolai972015年12月17日 21:32:33 +00:00Commented 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".
-
1\$\begingroup\$ Clever way of doing it. Frustrating that
.IndexOf()apparently has higher operating preference than unary-joinforcing the parens and quotes. :-/ \$\endgroup\$AdmBorkBork– AdmBorkBork2015年12月18日 14:09:50 +00:00Commented 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)
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
-
\$\begingroup\$ I don't think this handles 0 :( \$\endgroup\$David– David2015年12月18日 06:40:46 +00:00Commented Dec 18, 2015 at 6:40
-
\$\begingroup\$ @David Now it does. Thanks for noticing! It only cost 3 bytes :-) \$\endgroup\$Luis Mendo– Luis Mendo2015年12月18日 10:36:38 +00:00Commented Dec 18, 2015 at 10:36
-
\$\begingroup\$ now that clipboard
Gcontains the input (and implicit input), I guess this answer can be shortened by quite a lot, and all theYsneed to change toVanyway; I came up with10+:"@Vv]!GVXf1)for 16 bytes. \$\endgroup\$Giuseppe– Giuseppe2018年03月21日 17:21:35 +00:00Commented Mar 21, 2018 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– Luis Mendo2018年03月21日 17:41:10 +00:00Commented Mar 21, 2018 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
Ysneeded to change toVto use in the most up-to-date version of the interpreter. I'm always impressed with how much the language has improved! \$\endgroup\$Giuseppe– Giuseppe2018年03月21日 17:56:21 +00:00Commented 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.
-
\$\begingroup\$ Ideal for a classic
forloop...for($c='.';($x=$c.IndexOf("$args"))-lt0;$c+=++$i){}$xand 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){}$x51 bytes. (but I posted my 39 byte one as its own answer because it's a completely different approach :P). \$\endgroup\$TessellatingHeckler– TessellatingHeckler2015年12月18日 07:39:40 +00:00Commented Dec 18, 2015 at 7:39 -
1\$\begingroup\$ @TessellatingHeckler Nice way to rewrite the loop - thanks! I moved the
$cconcatenation into the loop to golf a semicolon. Now at 50. \$\endgroup\$AdmBorkBork– AdmBorkBork2015年12月18日 14:14:46 +00:00Commented 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|
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
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
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, (削除) 82 (削除ここまで) (削除) 73 (削除ここまで) 55 bytes
Migrated from the duplicate
x!b|or$zipWith(==)x b=0
x!(_:b)=1+x!b
(!(show=<<[1..]))
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.
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>
Husk, (削除) 6 (削除ここまで) 5 bytes
€ṁdNd
-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
-
1\$\begingroup\$ @Razetime Knew how you did it before I clicked the link! \$\endgroup\$Unrelated String– Unrelated String2020年11月13日 16:28:47 +00:00Commented Nov 13, 2020 at 16:28
Vyxal, 6 bytes
1+ɾṅḟ›
Try it Online! ɾṅḟ would be enough if not for the zero edgecase.
1+ɾṅḟ›
› # 1 +
ḟ # Index of input in
ṅ # Concatenation of
ɾ # 0...
1+ # 100+n
Perl 5, (削除) 42 (削除ここまで) 31 + 1 (-p) = 32 bytes
(join'',0..$_+10)=~/$_/;$_="@-"
Explanation
(join'',0..$_+10) # concatenate all of the numbers from 0 to 10 over the input
=~/$_/; # skip the first 0, then find the input
$_="@-" # @- holds the index of the start of the last match
-
\$\begingroup\$ Nice solution, can't get it smaller! I don't think you should need to add 10 though? The maximal place the number would be would be the number itself, right? \$\endgroup\$Dom Hastings– Dom Hastings2024年04月19日 10:59:52 +00:00Commented Apr 19, 2024 at 10:59
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
0 <= x <= 99, but it should theoretically work for integers higher than99. \$\endgroup\$