111

73

Let's say I want to answer the question "what are the first 400 palindromic prime numbers?"

The first approach that comes to my mind from the set of languages that I know is to use some sort of lazy list materialization, a la `IEnumerable`

(and `yield`

) in C#, generators in Python, or `sequence`

blocks in F#.

For example, in C#:

```
PrimesEnumerator().Where(n => n.ToString() == n.ToString().Reverse()).Take(400);
```

This would cause the PrimesGenerator to be pumped for primes long enough for the `Where()`

clause to find enough numbers that meet the requirement for `Take()`

to meet its quota.

The best I've come up with in Mathematica is something like:

```
i = 1; results = List[];
While[Length[results] != 400,
If[IntegerDigits[Prime[i]] == Reverse[IntegerDigits[Prime[i]]],
results = Append[results,Prime[i]]];
i = i + 1]
```

It surprises me that I end up writing in such an imperative style in Mathematica. Am I missing something that would let me write this entirely functionally? Maybe even with lazy lists?

Update:I took inspiration from WReach's work of art answer, and made a package that took his ideas and expanded them into a broad, general solution for lazy data in Mathematica. I describe its usage in an answer below.

@sblom your package is an interesting work. Some usage examples would further increase its value in my opinion. – faysou – 2012-04-09T11:54:05.993

The code could be streamlined a bit:

`For[i = 1; k = 1; results = {}, k <= 300, i++, If[IntegerDigits[Prime[i]] == Reverse[IntegerDigits[Prime[i]]], results = {results, Prime[i]}; k++]]; Flatten[results]`

. – J. M.'s ennui – 2012-01-28T03:46:15.1901Seems like most solutions to a "find the first N" type of problem suffers from "guess how big of a

`Range[]`

you need to iterate through". It seems, at least in the general case, that there's no great way to avoid that. Maybe I need to write a "Lazy Generators" package for Mathematica. – sblom – 2012-01-28T04:04:35.5703

Roman Maeder gave an implementation of lazy lists in one of his books (Mathematica Programmer). I used a technique described by @Sal, for a similar purposes: iterators - http://stackoverflow.com/questions/8596134/efficient-alternative-to-outer-on-sparse-arrays-in-mathematica/8609071#8609071, http://mathematica.stackexchange.com/questions/559/what-are-the-use-cases-for-different-scoping-constructs/569#569 (Module -> Advanced uses), more examples and links in my third post here: http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/5eff6213a0ab5f51.

– Leonid Shifrin – 2012-01-28T11:11:33.823@J.M., why

`results = {results, Prime[i]}; Flatten[results]`

instead of`results = Append[results,Prime[i]]`

? I'm guessing it's to defer reallocation costs for`results`

? – sblom – 2012-01-28T17:38:32.057@LeonidShifrin, that comment seems worthy of a credited answer. You'd certainly get an upvote from at least me. – sblom – 2012-01-28T17:39:52.333

The technique behind it was described in the aswer by @Sal already, so I did not think my additions would merit a separate answer. Thanks anyways, I am happy if that was helpful. – Leonid Shifrin – 2012-01-28T17:51:51.747

What is used in this question is very similar. Just pointing to a practical use on this very site.

– Szabolcs – 2012-01-28T17:53:16.720@sblom: it's a bit faster than

`Append[]`

/`AppendTo[]`

when I checked. You might want to experiment on your setup to compare. – J. M.'s ennui – 2012-01-28T18:09:14.600