martes, febrero 17, 2009

project euler - problema 4

Ahora que me hice un tiempo encare el cuarto ejercicio, facil, pero me costo sacarme de la cabeza tratar de hacer todo en lisp con recursion y usar el macro loop (que por cierto es el mas poderozo que he visto en cualquier lenguaje).

algunas cosas para observar:

no se si soy yo, pero usar progn y setq en lisp no me convence, siempre pense al principio en hacer todo recursivo y con let, pero parece que se complica a veces (no conozco una forma de evitar los lets nesteados, debe haber una forma pero no la conozco).

en cuanto a erlang no me gusta la diferencia de and andalso y or y orelse, pero parece que esta ahi por razones historicas, el pattern matching es adictivo, no me gusta que no pueda poner ; en el ultimo guard de un case.

hasta ahora vengo resolviendo el problema primero en python, despues en erlang y despues en lisp, por ahi eso condiciona la forma en la que lo resuelvo, pero siempre trato de usar la solucion que mas se adapta al lenguaje.

aca va el codigo

python

def is_palindromic(number):
'''return True if the number is a palindrome'''
number = str(number)

limit_start = len(number) / 2

if len(number) % 2 == 1:
limit_end = limit_start + 1
else:
limit_end = limit_start

return number[limit_start:] == number[:limit_end][::-1]

def get_largest_palindrome():
'''get the largest 3 digit palindrome'''
temp = 0

for i in range(999, 0, -1):
for j in range(i, 0, -1):
value = i * j
if is_palindromic(value):
if temp < value:
temp = value

return temp

print get_largest_palindrome()



lisp

(defun is-palindrome (num)
(progn
(setf str (format nil "~a" num))
(setf size (length str))
(setf first-half (truncate (/ size 2)))
(if (evenp size)
(setf second-half first-half)
; else
(setf second-half (+ first-half 1)))
(equal (subseq str 0 first-half) (reverse (subseq str second-half size)))))

(defun get-largest-palindrome ()
(progn
(setf temp 0)
(loop for i from 999 downto 0 do
(loop for j from i downto 0 do
(progn
(setq value (* i j))
(if (and (is-palindrome value) (> value temp))
(setq temp value)))))
temp))

(print (get-largest-palindrome))



erlang

-module(ej_004).
-compile(export_all).
%-export([get_largest_palindrome/0]).

is_palindrome(Number) ->
String = integer_to_list(Number),
Size = string:len(String),
FirstHalf = Size div 2,

case Size rem 2 == 1 of
false -> SecondHalf = FirstHalf + 1;
true -> SecondHalf = FirstHalf + 2
end,

FirstPart = string:substr(String, 1, FirstHalf),
SecondPart = lists:reverse(string:substr(String, SecondHalf, Size)),

FirstPart == SecondPart.

get_largest_palindrome(0, 0, Accum) -> Accum;
get_largest_palindrome(X, 0, Accum) -> get_largest_palindrome(X - 1, X - 1, Accum);

get_largest_palindrome(X, Y, Accum) ->
Value = X * Y,

case is_palindrome(Value) andalso Value > Accum of
true -> NewValue = Value;
false -> NewValue = Accum
end,

get_largest_palindrome(X, Y - 1, NewValue).

get_largest_palindrome(X, Accum) -> get_largest_palindrome(X, X, Accum).
get_largest_palindrome() -> get_largest_palindrome(999, 0).

No hay comentarios.:

Seguidores

Archivo del Blog