[erlang-questions] Question about lists:filter

Richard A. O'Keefe <>
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.


More information about the erlang-questions mailing list