martes, 22 de mayo de 2007

Cuando Funcional casi me defrauda (1º parte)

El otro día estaba en lo de un amigo que cursa Programación. Y encontré una explicación de práctica que me puse a revisar.

El problema consistía en: Dado un árbol binario no ordenado de productos (código, precio), informar el código del producto de mayor precio.

Código Pascal
   1:type
2: producto =
3: record
4: codigo : integer;
5: precio : real;
6: end;
7:
8: arbol = ^nodo;
9: nodo =
10: record
11: dato : producto;
12: izq, der : arbol;
13: end;
14:
15:function codProdMax (a : arbol) : integer;
16:var
17: max : real;
18: cod : integer;
19:
20:begin
21: max := -1;
22: cod := -1;
23: verPrecioMax(a, max, cod);
24: codProdMax := cod;
25:end;
26:
27:procedure verPrecioMax (a : arbol; var max : real;
28: var cod : integer);
29:begin
30: if (a <> nil) then
31: begin
32: if (a^.dato.precio > max) then
33: begin
34: max := a^.dato.precio;
35: cod := a^.dato.codigo;
36: end
37: verPrecioMax(a^.izq, max, cod);
38: verPrecioMax(a^.der, max, cod);
39: end;
40:end;


Por alguna razón, quizá estaba muy al pedo, se me ocurrió hacerlo en Haskell, y me quedó algo así:

   1:data Arbol a = Empty | Arbol a (Arbol a) (Arbol a)
2:
3:data Producto = Producto Int Float deriving (Eq, Show)
4:
5:codigo :: Producto -> Int
6:codigo (Producto c p) = c
7:
8:precio :: Producto -> Float
9:precio (Producto c p) = p
10:
11:
12:maxProd :: Producto -> Producto -> Producto
13:maxProd p1 p2 =
14: if precio p1 > precio p2 then
15: p1
16: else
17: p2


La función se podría haber hecho a partir de un fold sobre el árbol, pero quería probarlo rápido, así que hice una especie de pseudofold:

   1:funcArbol :: (a -> a -> a) -> a -> Arbol a -> a
2:funcArbol f valor Empty = valor
3:funcArbol f valor (Arbol x t1 t2) =
4: f x (f (funcArbol f valor t1) (funcArbol f valor t2))
5:
6:maxProdArbol = funcArbol maxProd (Producto 0 0.0)


Se puede hacer algo más directo, pero ya no estoy acostumbrado:

   1:maxProdArbol :: Arbol Producto -> Producto
2:maxProdArbol Empty = Producto 0 0.0
3:maxProdArbol (Arbol x t1 t2) =
4: maxProd x (maxProd
5: (maxProdArbol t1) (maxProdArbol t2))


Continuará...

No hay comentarios: