18
\$\begingroup\$

Background

The Copeland–Erdős constant is the concatenation of "0." with the base 10 representations of the prime numbers in order. Its value is

0.23571113171923293137414...

See also OEIS A033308.

Copeland and Erdős proved that this is a normal number. This implies that every natural number can be found at some point in the decimal expansion of the Copeland-Erdős constant.

The challenge

Given a positive integer, express it in base 10 (without leading zeros) and output the index of its first appearance within the sequence of decimal digits of the Copeland–Erdős constant.

Any reasonable input and output format is allowed, but input and output should be in base 10. In particular, the input can be read as a string; and in that case it can be assumed not to contain leading zeros.

Output may be 0-based or 1-based, starting from the first decimal of the constant.

The actual results may be limited by data type, memory or computing power, and thus the program may fail for some test cases. But:

  • It should work in theory (i.e. not taking those limitations into account) for any input.
  • It should work in practice for at least the first four cases, and for each of them the result should be produced in less than a minute.

Test cases

Output is here given as 1-based.

13       -->         7   # Any prime is of course easy to find
997      -->        44   # ... and seems to always appear at a position less than itself
999      -->      1013   # Of course some numbers do appear later than themselves
314      -->       219   # Approximations to pi are also present
31416    -->     67858   # ... although one may have to go deep to find them
33308    -->     16304   # Number of the referred OEIS sequence: check
36398    -->     39386   # My PPCG ID. Hey, the result is a permutation of the input!
1234567  -->  11047265   # This one may take a while to find
\$\endgroup\$
5
  • \$\begingroup\$ Seemingly related, but actually quite different. \$\endgroup\$
    – Luis Mendo
    Commented Jul 17, 2016 at 22:48
  • \$\begingroup\$ Okay, so what's the winning criterion? \$\endgroup\$ Commented Jul 18, 2016 at 1:58
  • \$\begingroup\$ Considering the detailed rules regarding I/O, I'm going to assume this is code golf and apply the tag. I hope this is what you had in mind. \$\endgroup\$
    – Dennis
    Commented Jul 18, 2016 at 2:22
  • \$\begingroup\$ @Dennis Yes, sorry, I forgot. Thanks for editing \$\endgroup\$
    – Luis Mendo
    Commented Jul 18, 2016 at 7:20
  • 3
    \$\begingroup\$ Related Find the number in the Champernowne constant \$\endgroup\$ Commented Jul 18, 2016 at 13:56

11 Answers 11

7
\$\begingroup\$

Python 2, 64 bytes

f=lambda n,k=2,m=1,s='':-~s.find(`n`)or f(n,k+1,m*k*k,s+m%k*`k`)

Returns the 1-based index. Test it on Ideone.

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

05AB1E, 14 bytes

Uses 0-indexed output. Prime functions in osabie are very inefficient. Code:

[NØJD¹å#]¹.Oð¢

Explanation:

[       ]        # Infinite loop...
 N               # Get the iteration value
  Ø              # Get the nth prime
   J             # Join the stack
    D            # Duplicate this value
     ¹å#         # If the input is in this string, break out of the loop
         ¹.O     # Overlap function (due to a bug, I couldn't use the index command)
            ð¢   # Count spaces and implicitly print

Uses the CP-1252 encoding. Try it online!.

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

Jelly, 17 bytes

ÆRDFṡL}i
Ḥçßç?
çD

Returns the 1-based index. Try it online! or verify most test cases.

I've verified the last test case locally; it took 8 minutes and 48 seconds.

How it works

çD        Main link. Argument: n (integer)

 D        Decimal; yield A, the array of base 10 digits of n.
ç         Call the second helper link with arguments n and A.


Ḥçßç?     Second helper link. Left argument: n. Right argument: A.

Ḥ         Unhalve; yield 2n.
    ?     If...
   ç        the first helper link called with 2n and A returns a non-zero integer:
 ç            Return that integer.
          Else:
  ß           Recursively call the second helper link with arguments 2n and A.


ÆRDFṡL}i  First helper link. Left argument: k. Right argument: A.

ÆR        Prime range; yield the array of all primes up to k.
  DF      Convert each prime to base 10 and flatten the resulting nested array.
     L}   Yield l, the length of A.
    ṡ     Split the flattened array into overlapping slices of length l.
       i  Find the 1-based index of A in the result (0 if not found).

Alternate version, 11 bytes (non-competing)

ÆRVw³
ḤÇßÇ?

The w atom did not exist when this challenge was posted. Try it online!

How it works

ḤÇßÇ?  Main link. Argument: n (integer)

Ḥ      Unhalve; yield 2n.
    ?  If...
   Ç     the helper link called with argument 2n returns a non-zero integer:
 Ç         Return that integer.
       Else:
  ß      Recursively call the main link with argument 2n.


ÆRVw³  Helper link. Argument: k (integer)

ÆR     Prime range; yield the array of all primes up to k.
  V    Eval; concatenate all primes, forming a single integer.
    ³  Yield the first command-line argument (original value of n).
   w   Windowed index of; find the 1-based index of the digits of the result to
       the right in the digits of the result to the left (0 if not found).
\$\endgroup\$
4
\$\begingroup\$

Actually, 19 bytes

╗1`r♂Pεj╜@íu`;)╓i@ƒ

Takes a string as input and outputs the 1-based index of the substring

Try it online!

Explanation:

╗1`r♂Pεj╜@íu`;)╓i@ƒ
╗                    push input to register 0
  `r♂Pεj╜@íu`;)      push this function twice, moving one copy to the bottom of the stack:
   r♂Pεj               concatenate primes from 0 to n-1 (inclusive)
        ╜@íu           1-based index of input, 0 if not found
1              ╓     find first value of n (starting from n = 0) where the function returns a truthy value
                i@   flatten the list and move the other copy of the function on top
                  ƒ  call the function again to get the 1-based index
\$\endgroup\$
4
\$\begingroup\$

Husk, 6 bytes

€ṁdİpd

Try it online!

Prime number infinite list babyyyyy

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Great! "prime related functions are generally terrible for time based challenges in husk" - apparently not in this instance...! \$\endgroup\$ Commented Oct 20, 2020 at 18:48
  • \$\begingroup\$ @DominicvanEssen This challenge is pretty generous in that regard. \$\endgroup\$
    – Razetime
    Commented Oct 21, 2020 at 2:16
3
\$\begingroup\$

Julia, 55 bytes

\(n,s="$n",r=searchindex(n|>primes|>join,s))=r>0?r:3n\s

Returns the 1-based index. Completes all test cases in under a second. Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Is there a reason why you shift the primes upper bound by 3 and not e.g. by 2? Also, is there a way to extend it to work for 0 on input shorter than ...=r>0?r:3(n+9)\s? \$\endgroup\$
    – charlie
    Commented Jul 25, 2016 at 13:14
  • \$\begingroup\$ 3 was slightly faster than 2 in my tests and didn't increase the byte count. For input 0, you could use -~n instead, but it would be a lot slower. \$\endgroup\$
    – Dennis
    Commented Jul 25, 2016 at 15:26
  • \$\begingroup\$ Thanks, -~3n\s (== (3n+1)\s) is good enough. \$\endgroup\$
    – charlie
    Commented Jul 26, 2016 at 7:08
3
\$\begingroup\$

Pyth, 17 bytes

 fhJxs`MfP_YSTz2J

Leading space is important.

Test suite.

\$\endgroup\$
1
  • \$\begingroup\$ @LuisMendo You could test it for me. \$\endgroup\$
    – Leaky Nun
    Commented Jul 18, 2016 at 9:10
2
\$\begingroup\$

J, 37 bytes

(0{":@[I.@E.[:;<@":@p:@i.@]) ::($:+:)

Input is given as a base 10 integer and the output uses zero-based indexing.

Usage

   f =: (0{":@[I.@E.[:;<@":@p:@i.@]) ::($:+:)
   f 1
4
   f 13
6
   f 31416
67857

Explanation

This first call treats the verb as a monad, however subsequent calls which may occur recursively treat it as a dyad.

0{":@[I.@E.[:;<@":@p:@i.@]  Input: n on LHS, k on RHS
                         ]  Get k
                      i.@   Get the range [0, 1, ..., k-1]
                   p:@      Get the kth prime of each
                ":@         Convert each to a string
              <@            Box each string
           [:;              Unbox each and concatenate to get a string of primes
     [                      Get n
  ":@                       Convert n to a string
      I.@E.                 Find the indices where the string n appears in
                            the string of primes
0{                          Take the first result and return it - This will cause an error
                            if there are no matches

(...) ::($:+:)  Input: n on RHS, k on LHS
(...)           Execute the above on n and k
      ::(    )  If there is an error, execute this instead
           +:   Double k
         $:     Call recursively on n and 2k
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Can you prove that this works? \$\endgroup\$
    – Leaky Nun
    Commented Jul 18, 2016 at 6:52
  • \$\begingroup\$ @LeakyNun Oh yes that's true, it technically only works for the test cases but it might not be found in the first n primes. \$\endgroup\$
    – miles
    Commented Jul 18, 2016 at 9:18
  • \$\begingroup\$ It doesn't work for n = 1 since the first prime is 2 and you need the first five primes to get the first occurrence of a 1. \$\endgroup\$
    – miles
    Commented Jul 18, 2016 at 13:30
2
\$\begingroup\$

Ruby -rprime, 48 bytes

0-based.

->n{s=""
Prime.find{s<<_1.to_s=~/#{n}/}
$`.size}

Attempt This Online!

\$\endgroup\$
2
\$\begingroup\$

Raku, 45 bytes

{{$~={$_ x.is-prime}(++$)}...*~~/$_/;$/.from}

Try it online!

Really had to dig deep to bring the byte count way down here. The code generates a warning, but oh well!

The first bracketed expression generates strings consisting of the concatenation of successive primes. ++$ increments an anonymous state variable, and that number is passed to an anonymous function { $_ x .is-prime }, which replicates the stringified number once if it's prime, and zero times (ie, to an empty string) if it isn't. That string is appended to another anonymous state variable that keeps the concatenation of all primes seen so far with $ ~=. The sequence looks like 2, 23, 23, 235, 235, 2357, 2357, 2357, 2357, 235711, ..., with a repeated element whenever there isn't a prime. Very inefficient!

The sequence terminates when the ending condition * ~~ /$_/ is met; that is, when the concatenated string of primes matches the input number interpolated into a regex. That has the side effect of storing the resulting Match object into $/. Then the function just returns $/.from, the starting position of the match in the string of primes.

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

PowerShell v2+, 90 bytes

for($a="0.";!($b=$a.IndexOf($args)+1)){for(;'1'*++$i-match'^(?!(..+)\1+$)..'){$a+=$i}}$b-2

Combines the logic of my Find the number in the Champernowne constant answer, coupled with the prime generation method of my Print the nth prime that contains n answer, then subtracts 2 to output the index appropriately (i.e., not counting the 0. at the start).

Takes input as a string. Finds the 999 one in about seven seconds on my machine, but the 33308 one in quite a bit longer (edit - I gave up after 90 minutes). Should theoretically work for any value up to index [Int32]::Maxvalue aka 2147483647, as that's the maximum length of .NET strings. Will likely run into memory issues long before that happens, however.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.