2
$\begingroup$

I want to find all prime-palindromic numbers up to 5000. Prime-palindromic numbers are numbers that themselves and their reverse digits are both primes. For example, 31 is a prime-palindromic number because both 31 and 13 are prime. Here is my code, but it somehow does not work.

 Select[Range@5000, PrimeQ[Join[FromDigits[Reverse[IntegerDigits[#]]], # ]] &]

enter image description here

$\endgroup$
12
  • $\begingroup$ possible duplicate of Functional style using lazy lists? $\endgroup$
    – RunnyKine
    Jul 31, 2014 at 6:23
  • $\begingroup$ The link above has great answers for this exact problem. $\endgroup$
    – RunnyKine
    Jul 31, 2014 at 6:23
  • $\begingroup$ @RunnyKine But it is way over complicated, isn't it? $\endgroup$
    – Lawerance
    Jul 31, 2014 at 6:24
  • $\begingroup$ Not really, look at the third answer with about 4 variations. $\endgroup$
    – RunnyKine
    Jul 31, 2014 at 6:26
  • $\begingroup$ @RunnyKine Got it. But I still want my code to work with the help of others. $\endgroup$
    – Lawerance
    Jul 31, 2014 at 6:28

5 Answers 5

3
$\begingroup$

Here you code

Select[Range@5000,(PrimeQ[#]&&PrimeQ[FromDigits[Reverse[IntegerDigits[#]]]])&]
$\endgroup$
4
  • $\begingroup$ Thanks a lot! That's what I'm looking for. $\endgroup$
    – Lawerance
    Jul 31, 2014 at 6:39
  • $\begingroup$ I also have a question. In my code, I was trying to make two lists with # into a single list by join. And then, I will apply PrimeQ. Do you know why it won't work, or do you have a better way to make the two into a single list? $\endgroup$
    – Lawerance
    Jul 31, 2014 at 6:41
  • 2
    $\begingroup$ @Lawerance, Join needs Lists as inputs. So if you want to do it your way here is how: Select[Range@5000, And @@ PrimeQ[Join[{FromDigits[Reverse[IntegerDigits[#]]]}, {#}]] &] $\endgroup$
    – RunnyKine
    Jul 31, 2014 at 6:45
  • $\begingroup$ @RunnyKine Thanks a lot! I think I need to rephrase my title. It is not about finding the prime numbers, but to join the list. $\endgroup$
    – Lawerance
    Jul 31, 2014 at 6:46
2
$\begingroup$

Let's see where you went wrong:

  • Join[a,b] is not {a,b}, you have to type Join[{a},{b}] if you want to use Join in this way.
  • The second argument of Select is a criterion function, it needs to return either true or false. Your function returns a list of boolean values instead. You need to check if all values in the list are true, so you need to use And.

Improvements of style:

  • Instead of Join[{a},{b}] you can simply write {a,b}.
  • Prefix notation (f@expr) can make your code look simpler.

Code:

Select[Range@5000, And @@ PrimeQ@{FromDigits@Reverse@IntegerDigits@#, #} &]
$\endgroup$
1
  • $\begingroup$ Thanks a lot! I now know where I got wrong. $\endgroup$
    – Lawerance
    Jul 31, 2014 at 6:57
1
$\begingroup$

You can also use Reap and Sow:

Reap[If[PrimeQ[FromDigits[Reverse@IntegerDigits[#]]], Sow[#]] & /@ 
Select[PrimeQ][Range[5000]]][[2, 1]]

Or more concisely as per comment by @bmf:

Reap[If[PrimeQ[IntegerReverse[#]], Sow[#]] & /@ Select[PrimeQ][Range[5000]]][[2, 1]]
$\endgroup$
3
  • $\begingroup$ it's a (+1) from me with a gentle suggestion. This is shorter Reap[If[PrimeQ[IntegerReverse[#]], Sow[#]] & /@ Select[PrimeQ][Range[5000]]][[2, 1]] in case you are interested :) $\endgroup$
    – bmf
    Apr 27, 2022 at 4:44
  • $\begingroup$ @bmf thank you and thank you more concise code $\endgroup$
    – ubpdqn
    Apr 27, 2022 at 4:45
  • $\begingroup$ don't mention it. my pleasure. it's a really nice answer!!! $\endgroup$
    – bmf
    Apr 27, 2022 at 4:45
1
$\begingroup$

Just rephrasing the accepted answer with the help of a function:

Clear[primePalindromicQ];
primePalindromicQ[n_ /; n ∈ PositiveIntegers] := 
 PrimeQ[n] && PrimeQ@FromDigits@Reverse@IntegerDigits@n

Usage:

Select[primePalindromicQ][Range[5000]]

enter image description here

$\endgroup$
0
$\begingroup$

About using Scan instead of Map when using Reap and Sow in @bmf's proposal

Using Map when using Reap and Sow:

(*My mate @bmf*)
Reap[If[PrimeQ[IntegerReverse[#]], Sow[#]] & /@ 
Select[PrimeQ][Range[5000]]][[2, 1]] // RepeatedTiming // First

(*0.00932226*)

UsingScan when using Reap and Sow:

Reap[Scan[If[PrimeQ[IntegerReverse[#]], Sow[#]] &, 
Select[Range[5000], PrimeQ]]][[2, 1]] // RepeatedTiming // First

(*0.0087359*)

The times obtained above using RepeatedTiming for both Map and Scan are quite similar, indicating that the efficiency of both methods is comparable for this data size. It's important to note that the real advantage of using Scan instead of Map in this context is to avoid creating an unnecessary intermediate list, but the actual improvement in execution time may be minor.

That said, the choice to use Scan instead of Map in this case is not just about efficiency. It is also a design choice that reflects the intent of the code. By using Scan, we indicate that the list of results produced by applying the function doesn't matter and that only the side effect is of interest (in this case, the seeding process with Sow).

In practice, for problems of this size, the execution time difference between Map and Scan is smaller. However, as the problem scales or is integrated into more complex code, these design decisions can have more significant implications for both efficiency and readability.

$\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.