Once again, since I am only doing this to learn Erlang, I simply went for the brute force approach: try all combinations of 3-digit numbers, multiply them, check whether the product is a palindrome, and remember the biggest one.
While working on this problem, I did learn a couple of interesting things about the if statement in Erlang which seem weird coming from a more traditional language like C++. In Erlang every if statement must have an else clause, even if you don't really need one. Also, you cannot call a function in the condition. Damien Katz's excellent blog on "What sucks about Erlang" discusses these restrictions as well as some other restrictions.
Project Euler has a one-minute rule which says that the run time of a solution must be less than one minute on a modestly powered computer. Although the run time of this solution was obviously less than one minute, I wondered how I would measure it in Erlang. It turns out that this is trivial: just call timer:tc(module, function, arguments). This is described in detail in this article on the trapexit website.
(erlide@cayle-spandons-computer.local)2> timer:tc(euler4, solve, []).
{444625,906609}
Here is my Erlang solution for Euler problem number 4:
%% Author: cayle.spandon
%% Created: Jan 9, 2009
%% Description: Project Euler, problem 4
%%
%% A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers
%% is 9009 = 91 × 99.
%%
%% Find the largest palindrome made from the product of two 3-digit numbers.
%%
%% Use the dumb as a brick brute force approach: try all combinations of two 3-digit numbers, multiply them, check if
%% the product is a palindrome, and remember the biggest one.
%%
%% I'm sure that the project Euler will have something much more clever, but -hey- I am trying to learn Erlang, not
%% trying to become a math genius.
-module(euler4).
-export([solve/0, reverse/1]).
reverse(N) ->
reverse(N, 0).
reverse(N, Reversed) ->
if
N == 0 -> Reversed;
true ->
NLastDigit = N rem 10,
reverse(N div 10, Reversed * 10 + NLastDigit)
end.
isPalindrome(N) ->
N == reverse(N).
solve() ->
solve(100, 100, 0).
solve(N1, N2, BestSoFar) ->
Product = N1 * N2,
case (Product > BestSoFar) and isPalindrome(Product) of
true -> NewBestSoFar = Product;
false -> NewBestSoFar = BestSoFar
end,
if
N1 < 999 -> solve(N1+1, N2, NewBestSoFar);
N1 == 999 ->
if
N2 < 999 -> solve(100, N2+1, NewBestSoFar);
N2 == 999 -> NewBestSoFar
end
end.
2 comments:
seems to be less than one minute:
C:\Asm>euler4
Euler 4
i 993 * j 913 = k 906609
70 ms
assembler sucks ;-)
reverse(N) -> reverse(N, 0).
reverse(0, Reversed) -> Reversed;
reverse(N, Reversed) -> reverse(N div 10, Reversed*10 + N rem 10).
Post a Comment