{"id":4481,"date":"2014-10-06T16:46:37","date_gmt":"2014-10-06T14:46:37","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=4481"},"modified":"2014-10-06T16:46:37","modified_gmt":"2014-10-06T14:46:37","slug":"i1m2014-ejercicios-de-definiciones-con-condicionales-guardas-o-patrones","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2014-ejercicios-de-definiciones-con-condicionales-guardas-o-patrones\/","title":{"rendered":"I1M2014: Ejercicios de definiciones con condicionales, guardas o patrones"},"content":{"rendered":"<p>En la clase de hoy del curso de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-14\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a> hemos comentado las soluciones de los ejercicios de la 2\u00aa relaci\u00f3n sobre definiciones con condicionales, guardas o patrones.<\/p>\n<p>Los ejercicios y su soluci\u00f3n se muestran a continuaci\u00f3n<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\n-- ---------------------------------------------------------------------\n-- Introducci\u00f3n                                                       --\n-- ---------------------------------------------------------------------\n\n-- En esta relaci\u00f3n se presentan ejercicios con definiciones elementales\n-- (no recursivas) de funciones que usan condicionales, guardas o\n-- patrones. \n-- \n-- Estos ejercicios se corresponden con el tema 4 cuyas transparencias\n-- se encuentran en  \n--    http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-14\/temas\/tema-4t.pdf\n\n-- ---------------------------------------------------------------------\n-- \u00a7 Librer\u00edas auxiliares                                             --\n-- ---------------------------------------------------------------------\n\nimport Test.QuickCheck\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1. Definir la funci\u00f3n \n--    divisionSegura :: Double -> Double -> Double\n-- tal que (divisionSegura x y) es x\/y si y no es cero y 9999 en caso\n-- contrario. Por ejemplo,\n--    divisionSegura 7 2  ==  3.5\n--    divisionSegura 7 0  ==  9999.0\n-- ---------------------------------------------------------------------\n\ndivisionSegura :: Double -> Double -> Double\ndivisionSegura _ 0 = 9999\ndivisionSegura x y = x\/y\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2.1. La disyunci\u00f3n excluyente xor de dos f\u00f3rmulas se\n-- verifica si una es verdadera y la otra es falsa. Su tabla de verdad\n-- es\n--    x     | y     | xor x y\n--    ------+-------+---------\n--    True  | True  | False \n--    True  | False | True\n--    False | True  | True\n--    False | False | False\n--    \n-- Definir la funci\u00f3n \n--    xor1 :: Bool -> Bool -> Bool\n-- tal que (xor1 x y) es la disyunci\u00f3n excluyente de x e y, calculada a\n-- partir de la tabla de verdad. Usar 4 ecuaciones, una por cada l\u00ednea\n-- de la tabla. \n-- ---------------------------------------------------------------------\n\nxor1 :: Bool -> Bool -> Bool\nxor1 True  True  = False \nxor1 True  False = True\nxor1 False True  = True\nxor1 False False = False\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2.2. Definir la funci\u00f3n \n--    xor2 :: Bool -> Bool -> Bool\n-- tal que (xor2 x y) es la disyunci\u00f3n excluyente de x e y, calculada a\n-- partir de la tabla de verdad y patrones. Usar 2 ecuaciones, una por\n-- cada valor del primer argumento. \n-- ---------------------------------------------------------------------\n\nxor2 :: Bool -> Bool -> Bool\nxor2 True  y = not y\nxor2 False y = y\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2.3. Definir la funci\u00f3n \n--    xor3 :: Bool -> Bool -> Bool\n-- tal que (xor3 x y) es la disyunci\u00f3n excluyente de x e y, calculada \n-- a partir de la disyunci\u00f3n (||), conjunci\u00f3n (&&) y negaci\u00f3n (not). \n-- Usar 1 ecuaci\u00f3n. \n-- ---------------------------------------------------------------------\n\n-- 1\u00aa definici\u00f3n:\nxor3 :: Bool -> Bool -> Bool\nxor3 x y = (x || y) && not (x && y)\n\n-- 2\u00aa definici\u00f3n:\nxor3b :: Bool -> Bool -> Bool\nxor3b x y = (x && not y) || (y && not x)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2.4. Definir la funci\u00f3n \n--    xor4 :: Bool -> Bool -> Bool\n-- tal que (xor3 x y) es la disyunci\u00f3n excluyente de x e y, calculada\n-- a partir de desigualdad (\/=). Usar 1 ecuaci\u00f3n.\n-- ---------------------------------------------------------------------\n\nxor4 :: Bool -> Bool -> Bool\nxor4 x y = x \/= y\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2.5. Comprobar con QuickCheck que las cuatros definiciones\n-- de xor son equivalentes.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_xor_equivalentes :: Bool -> Bool -> Bool\nprop_xor_equivalentes x y =\n    xor1 x y == xor2 x y &&\n    xor2 x y == xor3 x y &&\n    xor3 x y == xor4 x y \n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_xor_equivalentes\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3. Las dimensiones de los rect\u00e1ngulos puede representarse \n-- por pares; por ejemplo, (5,3) representa a un rect\u00e1ngulo de base 5 y \n-- altura 3. \n-- \n-- Definir la funci\u00f3n \n--    mayorRectangulo :: (Num a, Ord a) => (a,a) -> (a,a) -> (a,a)\n-- tal que (mayorRectangulo r1 r2) es el rect\u00e1ngulo de mayor \u00e1rea ente\n-- r1 y r2. Por ejemplo,  \n--    mayorRectangulo (4,6) (3,7)  ==  (4,6)\n--    mayorRectangulo (4,6) (3,8)  ==  (4,6)\n--    mayorRectangulo (4,6) (3,9)  ==  (3,9)\n-- ---------------------------------------------------------------------\n\nmayorRectangulo :: (Num a, Ord a) => (a,a) -> (a,a) -> (a,a)\nmayorRectangulo (a,b) (c,d) | a*b >= c*d = (a,b)\n                            | otherwise  = (c,d)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 4.1. Definir la funci\u00f3n \n--    intercambia :: (a,b) -> (b,a)\n-- tal que (intercambia p)  es el punto obtenido intercambiando las\n-- coordenadas del punto p. Por ejemplo, \n--    intercambia (2,5)  ==  (5,2)\n--    intercambia (5,2)  ==  (2,5)\n-- ---------------------------------------------------------------------\n\nintercambia :: (a,b) -> (b,a)\nintercambia (x,y) = (y,x)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 4.2. Comprobar con QuickCheck que la funci\u00f3n intercambia es\n-- idempotente; es decir, si se aplica dos veces es lo mismo que no\n-- aplicarla ninguna.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_intercambia :: (Int,Int) -> Bool\nprop_intercambia p = intercambia (intercambia p) == p\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_intercambia\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 5.1. Definir la funci\u00f3n \n--    distancia :: (Double,Double) -> (Double,Double) -> Double\n-- tal que (distancia p1 p2) es la distancia entre los puntos p1 y\n-- p2. Por ejemplo, \n--    distancia (1,2) (4,6)  ==  5.0\n-- ---------------------------------------------------------------------\n \ndistancia :: (Double,Double) -> (Double,Double) -> Double\ndistancia (x1,y1) (x2,y2) = sqrt((x1-x2)^2+(y1-y2)^2)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 5.2. Comprobar con QuickCheck que se verifica la propiedad\n-- triangular de la distancia; es decir, dados tres puntos p1, p2 y p3,\n-- la distancia de p1 a p3 es menor o igual que la suma de la distancia\n-- de p1 a p2 y la de p2 a p3.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_triangular :: (Double,Double) -> (Double,Double) -> (Double,Double)\n                -> Bool\nprop_triangular p1 p2 p3 =\n    distancia p1 p3 <= distancia p1 p2 + distancia p2 p3\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_triangular\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 6.1. Definir una funci\u00f3n \n--    ciclo :: [a] -> [a]\n-- tal que (ciclo xs) es la lista obtenida permutando c\u00edclicamente los\n-- elementos de la lista xs, pasando el \u00faltimo elemento al principio de\n-- la lista. Por ejemplo, \n--    ciclo [2,5,7,9]  == [9,2,5,7]\n--    ciclo []         == []\n--    ciclo [2]        == [2]\n-- ---------------------------------------------------------------------\n\nciclo :: [a] -> [a]\nciclo [] = []\nciclo xs = last xs : init xs\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 6.2. Comprobar que la longitud es un invariante de la\n-- funci\u00f3n ciclo; es decir, la longitud de (ciclo xs) es la misma que la\n-- de xs.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_ciclo :: [Int] -> Bool \nprop_ciclo xs = length (ciclo xs) == length xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_ciclo\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7. Definir la funci\u00f3n \n--    numeroMayor :: (Num a, Ord a) => a -> a -> a\n-- tal que (numeroMayor x y) es el mayor n\u00famero de dos cifras que puede\n-- construirse con los d\u00edgitos x e y. Por ejemplo,  \n--    numeroMayor 2 5 ==  52\n--    numeroMayor 5 2 ==  52\n-- ---------------------------------------------------------------------\n\n-- 1\u00aa definici\u00f3n:\nnumeroMayor :: (Num a, Ord a) => a -> a -> a\nnumeroMayor x y = 10 * max x y + min x y\n\n-- 2\u00aa definici\u00f3n:\nnumeroMayor2 :: (Num a, Ord a) => a -> a -> a\nnumeroMayor2 x y | x > y     = 10*x+y\n                 | otherwise = 10*y+x\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8. Definir la funci\u00f3n \n--    numeroDeRaices :: (Num t, Ord t) => t -> t -> t -> Int\n-- tal que (numeroDeRaices a b c) es el n\u00famero de ra\u00edces reales de la\n-- ecuaci\u00f3n a*x^2 + b*x + c = 0. Por ejemplo,\n--    numeroDeRaices 2 0 3    ==  0\n--    numeroDeRaices 4 4 1    ==  1\n--    numeroDeRaices 5 23 12  ==  2\n-- ---------------------------------------------------------------------\n\nnumeroDeRaices :: (Num t, Ord t) => t -> t -> t -> Int\nnumeroDeRaices a b c | d < 0     = 0\n                     | d == 0    = 1\n                     | otherwise = 2\n    where d = b^2-4*a*c\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 9.1. Definir la funci\u00f3n \n--    raices :: Double -> Double -> Double -> [Double]\n-- tal que (raices a b c) es la lista de las ra\u00edces reales de la\n-- ecuaci\u00f3n ax^2 + bx + c = 0. Por ejemplo, \n--    raices 1 3 2    ==  [-1.0,-2.0]\n--    raices 1 (-2) 1 ==  [1.0,1.0]\n--    raices 1 0 1    ==  []\n-- ---------------------------------------------------------------------\n\nraices :: Double -> Double -> Double -> [Double]\nraices a b c \n    | d >= 0    = [(-b+e)\/t,(-b-e)\/t]\n    | otherwise = []\n    where d = b^2 - 4*a*c\n          e = sqrt d\n          t = 2*a\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 9.2. Definir el operador\n--    (~=) :: (Fractional a, Ord a) => a -> a -> Bool\n-- tal que (x ~= y) se verifica si x e y son casi iguales; es decir si\n-- el valor absoluto de su diferencia es menor que una mil\u00e9sima. Por\n-- ejemplo, \n--    12.3457 ~= 12.3459  ==  True\n--    12.3457 ~= 12.3479  ==  False\n-- ---------------------------------------------------------------------\n\n(~=) :: (Fractional a, Ord a) => a -> a -> Bool\nx ~= y  = abs (x-y) < 0.001\n\n-- --------------------------------------------------------------------- \n-- Ejercicio 9.3. Comprobar con QuickCheck que la suma de las ra\u00edces\n-- de la ecuaci\u00f3n ax^2 + bx + c = 0 (con a no nulo) es -b\/a y su\n-- producto es c\/a.\n--\n-- Nota. En la comparaci\u00f3n usar ~= en lugar de ==\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_raices :: Double -> Double -> Double -> Property\nprop_raices a b c =\n    a \/= 0 && not (null xs) ==> sum xs ~= (-b\/a) && product xs ~= (c\/a)\n    where xs = raices a b c\n      \n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck prop_raices\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 10. En geometr\u00eda, la f\u00f3rmula de Her\u00f3n, descubierta por\n-- Her\u00f3n de Alejandr\u00eda, dice que el \u00e1rea de un tri\u00e1ngulo cuyo lados\n-- miden a, b y c es la ra\u00edz cuadrada de s(s-a)(s-b)(s-c) donde s es el\n-- semiper\u00edmetro \n--    s = (a+b+c)\/2\n-- \n-- Definir la funci\u00f3n \n--    area :: Double -> Double -> Double -> Double \n-- tal que (area a b c) es el \u00e1rea del tri\u00e1ngulo de lados a, b y c. Por\n-- ejemplo, \n--    area 3 4 5  ==  6.0\n-- ---------------------------------------------------------------------\n\narea :: Double -> Double -> Double -> Double \narea a b c = sqrt (s*(s-a)*(s-b)*(s-c))\n    where s = (a+b+c)\/2\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 11.1. Los intervalos cerrados se pueden representar mediante\n-- una lista de dos n\u00fameros (el primero es el extremo inferior del\n-- intervalo y el segundo el superior). \n-- \n-- Definir la funci\u00f3n \n--    interseccion :: Ord a => [a] -> [a] -> [a]\n-- tal que (interseccion i1 i2) es la intersecci\u00f3n de los intervalos i1 e\n-- i2. Por ejemplo,\n--    interseccion [] [3,5]  ==  []\n--    interseccion [3,5] []  ==  []\n--    interseccion [2,4] [6,9]  ==  []\n--    interseccion [2,6] [6,9]  ==  [6,6]\n--    interseccion [2,6] [0,9]  ==  [2,6]\n--    interseccion [2,6] [0,4]  ==  [2,4]\n--    interseccion [4,6] [0,4]  ==  [4,4]\n--    interseccion [5,6] [0,4]  ==  []\n-- ---------------------------------------------------------------------\n\ninterseccion :: Ord a => [a] -> [a] -> [a]\ninterseccion [] _ = []\ninterseccion _ [] = []\ninterseccion [a1,b1] [a2,b2]\n    | a <= b    = [a,b]\n    | otherwise = []\n    where a = max a1 a2\n          b = min b1 b2\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 11.2. Comprobar con QuickCheck que la intersecci\u00f3n de\n-- intervalos es conmutativa.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_interseccion :: Int -> Int -> Int -> Int -> Property\nprop_interseccion a1 b1 a2 b2 =\n    a1 <= b1 &#038;&#038; a2 <= b2 ==>\n    interseccion [a1,b1] [a2,b2] == interseccion [a2,b2] [a1,b1]\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_interseccion\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 12.1. Los n\u00fameros racionales pueden representarse mediante\n-- pares de n\u00fameros enteros. Por ejemplo, el n\u00famero 2\/5 puede\n-- representarse mediante el par (2,5). \n-- \n-- Definir la funci\u00f3n \n--    formaReducida :: (Integer,Integer) -> (Integer,Integer) \n-- tal que (formaReducida x) es la forma reducida del n\u00famero racional\n-- x. Por ejemplo, \n--    formaReducida (4,10)  ==  (2,5)\n--    formaReducida (0,5)   ==  (0,1)\n-- ---------------------------------------------------------------------\n\nformaReducida :: (Integer,Integer) -> (Integer,Integer) \nformaReducida (0,_) = (0,1)\nformaReducida (a,b) = (a `div` c, b  `div` c)\n    where c = gcd a b\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 12.2. Definir la funci\u00f3n \n--    sumaRacional :: (Integer,Integer) -> (Integer,Integer) -> (Integer,Integer)\n-- tal que (sumaRacional x y) es la suma de los n\u00fameros racionales x e\n-- y, expresada en forma reducida. Por ejemplo, \n--    sumaRacional (2,3) (5,6)  ==  (3,2)\n--    sumaRacional (3,5) (-3,5) ==  (0,1)\n-- ---------------------------------------------------------------------\n\nsumaRacional :: (Integer,Integer) -> (Integer,Integer) -> (Integer,Integer)\nsumaRacional (a,b) (c,d) = formaReducida (a*d+b*c, b*d)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 12.3. Definir la funci\u00f3n \n--    productoRacional :: (Integer,Integer) -> (Integer,Integer) \n--                     -> (Integer,Integer)\n-- tal que (productoRacional x y) es el producto de los n\u00fameros\n-- racionales x e y, expresada en forma reducida. Por ejemplo, \n--    productoRacional (2,3) (5,6)  ==  (5,9)\n-- ---------------------------------------------------------------------\n\nproductoRacional :: (Integer,Integer) -> (Integer,Integer)\n                 -> (Integer,Integer)\nproductoRacional (a,b) (c,d) = formaReducida (a*c, b*d)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 12.4. Definir la funci\u00f3n \n--    igualdadRacional :: (Integer,Integer) -> (Integer,Integer) -> Bool\n-- tal que (igualdadRacional x y) se verifica si los n\u00fameros racionales\n-- x e y son iguales. Por ejemplo, \n--    igualdadRacional (6,9) (10,15)  ==  True\n--    igualdadRacional (6,9) (11,15)  ==  False\n--    igualdadRacional (0,2) (0,-5)   ==  True\n-- ---------------------------------------------------------------------\n\nigualdadRacional :: (Integer,Integer) -> (Integer,Integer) -> Bool\nigualdadRacional (a,b) (c,d) = \n    a*d == b*c\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 12.5. Comprobar con QuickCheck la propiedad distributiva\n-- del producto racional respecto de la suma.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_distributiva :: (Integer,Integer) -> (Integer,Integer) -> (Integer,Integer)\n                     -> Property\nprop_distributiva x y z =\n    snd x \/= 0 && snd y \/= 0 && snd z \/= 0 ==>\n    igualdadRacional (productoRacional x (sumaRacional y z))\n                     (sumaRacional (productoRacional x y)\n                                   (productoRacional x z))\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_distributiva\n--    +++ OK, passed 100 tests.\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>En la clase de hoy del curso de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas hemos comentado las soluciones de los ejercicios de la 2\u00aa relaci\u00f3n sobre definiciones con condicionales, guardas o patrones. Los ejercicios y su soluci\u00f3n se muestran a continuaci\u00f3n<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false},"categories":[238],"tags":[270,305,126],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":false,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/4481"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/comments?post=4481"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/4481\/revisions"}],"predecessor-version":[{"id":4482,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/4481\/revisions\/4482"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=4481"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=4481"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=4481"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}