Palindromic Primes without 11

Python 2, 76 73 72 70 69 68 bytes

n=input();c=k=m=11
while n:m*=k/c;k+=c;n-=`k`==`k`[::~m%k-c]
print k

Thanks to @WheatWizard for golfing off 3 bytes!

Thanks to @ØrjanJohansen for golfing off 1 byte!

Thanks to @xnor and @ØrjanJohansen for paving the way to 68 bytes!

Input is 0-indexed. Try it online! or verify the first 31 test cases.

Background

Recall that Wilson's theorem states that for all integers p > 1,

meaning that (p - 1)! + 1 is evenly divisible by p if and only if p is prime.

If p > 1 is not prime, it is composite; let q be the smallest prime divisor of p. Clearly, q ≤ p/q. There are two cases:

  • If q = p/q, we have that p = q².

    If q = 2, (p - 1)! = 3! = 6, so (p - 1)! is congruent to 2 modulo p.

    If p/q = q > 2, so 2q < p. This way, q and 2q are both among 1, …, p - 1, whose product is the factorial of p - 1, so 2p = 2q² = q · 2q divides (p - 1)! evenly.

  • If q < p/q, q and p/q are both among 1, …, p - 1, so p = q · p/q divides (p - 1)! evenly.

Summing up,

for all integers p > 1.

Now, for all integer congruences and all integers a, b, and c, the following holds.

When a = -1, b = 11, and c = -1, we follow that

and, since 21 and -23 are congruent modulo 44 and -1 and 11p-1 are congruent modulo 11p, we arrive at the following conclusion.

For all possible values of p, the outcome (11, 21, or 11p - 1) will fall in the range 0, …, 11p - 1, so these values match those that will be returned by Python's % operator.

How it works

We initialize c, k, and m to 11 after the saving the input in n. c will be constant for the remainder of the program. Since there are three occurrences of c on the following line and assigning c costs only two bytes, this saves a byte. k can be thought of 11p using the meaning of p from the previous paragraph; initially, k = 11 = 11 · 1!. m takes the place of 11 · (p - 1)!; initially, m = 11 = 11 · 0!. k and m will satisfy the relationship m = 11 · (k/11)! at all times.

n represents the number of “Stephen's palindromes” we have to find. Since k = 11 initially, we can output k verbatim without further computation. However, when n is positive, we enter the while loop. The loop begins by multiplying m by k/c = p, then adding 11 to k, thus incrementing p. If k is a member of the sequence, we subtract 1 from n and start over. Once n reaches 0, we found the sequence member at the desired index and break out of the loop, then print the last value of k.

The expression

`k`==`k`[::~m%k-c]

performs the actual test, and it's result (True / 1 for sequence members, 0 / False otherwise) is subtracted from n. As seen before, ~m % k = (-m - 1) % k = (-11 · (p - 1)! - 1) % 11p equals 10 if p is prime, 21 if p = 4, and 11p - 1 > 43 if p > 4 is composite. Thus, after subtracting c = 11, we're left with -1 for prime p and a positive integer larger than 9 otherwise.

For prime p, ​`k`[::-1] gives us the string representation of k with reversed digit order, so comparing it to ​`k`​ checks whether k is a palindrome. If it is, all conditions are fulfilled and k is a sequence member. However, if p is not prime, the large range step and the fact that k will always have more than one digit mean that ​`k`[::-1] cannot have the same number of digits as ​`k`​, let alone be equal to it.


Jelly, 18 13 bytes

ṬÆẸש11ŒḂµ#ṛ®

For some reason, this is much slower than my initial revision, despite doing exactly the same.

Try it online!

N = 127

dennis-home:~$ time jelly eun 'ṬÆẸש11ŒḂµ#ṛ®' <<< 127
997799

real    1m43.745s
user    1m43.676s
sys     0m0.113s

How it works

ṬÆẸש11ŒḂµ#ṛ®  Main link. No arguments.

         µ     Combine all links to the left into a chain.
          #    Read an integer n from STDIN and call the chain monadically, with
               argument k = 0, 1, 2, ... until n values of k result in a truthy
               output. Return the array of all matching values of k.
Ṭ                Untruth; yield [0, 0, 0, ..., 1] (k-1 zeroes followed by a 1) or
                 [] if k = 0.
 ÆẸ              Unexponents; consider the resulting array as exponents of the
                 sequence of primes and yield the corresponding integer. For k = 0,
                 this yields 1. For k > 0, it yields the k-th prime.
   ש11          Multiply the result by 11 and copy the product to the register.
       ŒḂ        Test if the product is a palindrome.
           ṛ®  Replace the resulting array with the integer in the register.

Brachylog, 17 bytes

:I{11|ṗ×₁₁≜.↔}ᶠ⁽t

Try it online!

This is 1-indexed.

Explanation

:I{          }ᶠ⁽t    Find the Input'th result of the following:
   11                  Output = 11
     |                 Or
          ≜.           Output is an integer…
      ṗ×₁₁             …which is the result of multiplying a prime by 11…
           .↔          …and Output reversed is still the Output

Two realizations with this answer:

  • I need to fix the fact that superscript passing to metapredicates (with ) does not work if there is no input to pass (which is why I have to add :I).
  • I need to add a metapredicate to get the Nth result of a predicate (which would avoid using ᶠ⁽t and instead e.g. ⁿ⁽).

Implementing both changes would make that answer 14 bytes.