Fond Memories of Past Primes
Pyth, 22 bytes
f&}TPTqQlf}YPY{sMP.:`T
Demonstration, Test Harness
Explanation:
f&}TPTqQlf}YPY{sMP.:`T
Implicit: Q = eval(input())
f Starting at T=1 and counting up, return the first T where
`T repr(T)
.: all substrings
P except T itself
sM converted to integers
{ unique examples only
f filter on
}YPY Y is in the prime factorization of Y, e.g. Y is prime.
qQl Q == len of the above, that is, T has memory Q,
&}TPT and T is prime, (is in its prime factorization.)
CJam, 33 31 30 bytes
1{)__mp*{_mp2$s@s#)*},,easi^}g
This is a full program that reads the input as a command-line argument.
Try it online in the CJam interpreter.
Test run
$ time cjam <(echo '1{)__mp*,{_mp2$s@s#)*},,easi^}g') 9
11317
real 0m3.562s
user 0m4.065s
sys 0m0.177s
How it works
1 e# Push I := 1 on the stack.
{ e# Do:
)__ e# Increment I and push two copies.
mp* e# Check the last copy for primality and multiply with the first copy.
e# This pushes R := I if I is prime and R := 0 if it is composite.
{ e# Filter; for each J in [0 ... R-1]:
_mp e# Push a copy of J and check for primality.
2$s e# Push a copy of I and cast to string.
@s e# Rotate the original J on top of the stack and cast to string.
# e# Find the index (-1 if not found) of the latter in the former.
)* e# Increment the index and multiply it with the result from `mp'.
e# This yields 0 iff J is composite or not a subtring of I.
}, e# Keep J if the product is non-zero.
, e# Push the length of the filtered range.
easi e# Cast the array of command-line arguments to string, then to integer.
^ e# XOR it with the length of the filtered range.
}g e# Repeat while theresult is non-zero.
CJam, 40 bytes
li2sa{_)\{1$\#)},,3$-}{i{)_mp!}gsa+}w]W=
Try it online
I'm sure this comes as a big shocker, but it is in fact longer than the solution Dennis posted. Well, not really, since I didn't even have very high hopes myself. But I wanted to give it a shot anyway. And since it's working, looks pretty reasonable to me, and I believe it is sufficiently different to at least be of some interest, I thought I'd post it anyway.
The basic idea here is that I build a list of prime numbers in a loop, adding the next larger prime number to the list in each step. To check for termination, I count how many elements other than the last element in the list are a substring of the last element. If this count is equal to the input n
, we're done.
Explanation:
li Get input and convert to integer.
2sa Seed list of primes with ["2"]. The primes are stored as strings to make
the later substring search more streamlined.
{ Start of while loop condition.
_ Copy list of primes.
) Pop off last prime from list.
\ Swap remaining list to top.
{ Start of filter block for substring matches with all smaller primes.
1$ Copy test prime to top.
\ Swap the smaller prime to top to get correct order for substring search.
# Search.
) Increment to get truthy value (Search returns -1 if not found).
}, End of filter. We have a list of smaller primes that are substrings now.
, Count list entries.
3$ Copy input n to top.
- Subtract the two for comparison. If they are different, continue loop.
} End of while loop condition.
{ Start of while loop body. We need to generate the next prime.
i The largest prime so far is still on the stack, but as string.
Convert it to integer.
{ Start of loop for prime candidates.
) Increment current candidate value.
_mp Check if it is prime.
! Negate, loop needs to continue if it is not a prime.
}g End loop for prime candidates. On exit, next prime is found.
sa+ Convert it to string, and add it to list of primes.
}w End of while loop body.
]W= Solution is at top of stack. Discard other stack entries.