Richard A. O'Keefe ok@REDACTED
Thu Aug 29 00:22:09 CEST 2013

```On 28/08/2013, at 11:54 PM, Nadav Chernin wrote:

> Hi, all
>
> I'm learning Erlang with Project Euler.
>
> This is my solution for problem 4.
>
>
> -module(euler).
> -export([problem4/0]).
>
> cand()->[X*Y||X<-lists:seq(100,999),Y<-lists:seq(100,999)].
> isPal(X)->integer_to_list(X)==lists:reverse(integer_to_list(X)).
> problem4()->lists:max(lists:filter(fun(A)->isPal(A) end,cand())).

Other people have pointed out that "isPal" should have been
"fun isPal/1".  Let me be the one to remind you that your
keyboard has a space key.

candidates() ->
Range = lists:seq(100, 999),
[X*Y || X <- Range, Y <- Range].

is_palindrome(X) ->
integer_to_list(X) == lists:reverse(integer_to_list(X)).

problem_4() ->
lists:max([A || A <- candidates(), is_palindrome(A)]).

is much easier to read.  Now it is easy to see that
candidates() contains a _lot_ of duplication.  We cannot
distinguish X * Y from Y * X, so why generate both?

candidates() ->
Range = lists:seq(100, 999),
[X * Y || X <- Range, Y <- Range, Y >= X].
%                                     ^^^^^^

Then there is the question about why you were bothering to
pass is_palindrome/1 as an argument at all instead of using
a list comprehension:

Another thing that might speed this up is noting that
you are generating numbers in the range 10,000 to 999,801,
so

problem_4() ->
lists:max([A || A <- candidates(),
case integer_to_list(A)
of [X,Y,_,Y,X]   -> true
; [X,Y,Z,Z,Y,X] -> true
; _             -> false
end]).

makes half as many lists.

```