Looking for shorter alternatives to `range(...)`
Make it a single loop
As is, you have two loops: one iterating over x
that might be palindromic primes, another iterating over i
to check if x
is prime by trial division. As you noticed, loops is Python take many characters, often to write range
, but also to write while _:
or for x in _
. So, a golfed Python solution should take pains to use as few loops as possible.
feersum's comment "The best-golfed programs often make surprising connections between different part of the programs" is very applicable here. The prime-checking might seem like a separate subroutine for which all(x%i for i in range(2,x))
is the classic expression. But we'll do it another way.
The idea is to use Wilson's Theorem. For each potential prime k
, we keep a running product of (k-1)!
, and check is it's a multiple of k
. We can keep track of (k-1)!
while we test potential k
to be prime palindromes by keeping a running product P
.
Actually, we'll use the stronger version of Wilson's Theorem that (k-1)! % k
equals 0 for composite k
and only for composite numbers, except k=4
gives 2
, and so (k-1)!**2 % k
equals 0
exactly for composite numbers. We'll update P
to equal k!**2
via the update P*=k*k
.
(See this answer for this method used to find primes in Python.)
Putting it all together:
def p(n):
k=P=1
while(`k`!=`k`[::-1])+(k<=n)+(P%k==0):P*=k*k;k+=1
return k
This isn't yet fully golfed -- the condition in particular is written inefficiently.
We can compress the condition to check that k
is a palindrome while at the time enforcing the other conditions via a chained inequality.
def p(n):
k=P=1
while`k`*(P%k>0>n-k)!=`k`[::-1]:P*=k*k;k+=1
return k
AFAIK, not really.
Range is commonly used in python golfs because it is the shortest way to generate lists of increasing/decreasing numbers.
That said, it appears to be slightly (7 bytes) shorter to avoid using range and instead call a wrapped while loop:
def p(n):
n+=1
while`n`*all(n%i for i in range(2,n))!=`n`[::-1]:n+=1
return n
Thanks to @xnor (as always) for improving the while condition's logic :)