{"id":892,"date":"2014-12-30T08:21:09","date_gmt":"2014-12-30T06:21:09","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=892"},"modified":"2015-04-26T20:22:10","modified_gmt":"2015-04-26T18:22:10","slug":"la-funcion-suelo","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/la-funcion-suelo\/","title":{"rendered":"La funci\u00f3n suelo"},"content":{"rendered":"<p>La <a href=\"http:\/\/bit.ly\/1JW1PVK\">funci\u00f3n suelo<\/a> asigna a cada n\u00famero real el n\u00famero entero m\u00e1s pr\u00f3ximo por defecto; es decir, el mayor n\u00famero entero igual o menor que ese n\u00famero real. Por ejemplo, al -2.4 le asigna el -3 y al 1.7 el 1.<\/p>\n<p>Haskell tiene una implementaci\u00f3n de la funci\u00f3n suelo llamada floor. El objetivo de este ejercicio es redefinir dicha funci\u00f3n; es decir, definir (sin usar floor, round ni ceiling) la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   suelo :: Float -> Integer\n<\/pre>\n<p>tal que (suelo x) es el suelo de x. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   suelo (-2.7)  ==  -3\n   suelo (-2.4)  ==  -3\n   suelo (-2)    ==  -2\n   suelo 0       ==   0\n   suelo 2       ==   2\n   suelo 2.4     ==   2\n   suelo 2.7     ==   2\n<\/pre>\n<p>Comprobar con QuickCheck que las funciones suelo y floor son equivalentes.<\/p>\n<h4>Soluciones<\/h4>\n<pre lang=\"haskell\">\nimport Test.QuickCheck\n\n-- 1\u00aa definici\u00f3n (por comprensi\u00f3n)\n-- ===============================\n\nsuelo1 :: Float -> Integer\nsuelo1 x | x < 0     = head [m | m <- [-1,-2..], fromIntegral m <= x] \n         | otherwise = head [m | m <- [1..], x < fromIntegral m] - 1\n\n-- 2\u00aa definici\u00f3n (con until)\n-- =========================\n\nsuelo2 :: Float -> Integer\nsuelo2 x | x < 0     = until (`menorI` x) (subtract 1) (-1)\n         | otherwise = until (x `menor`) (+1) 1 - 1\n         where menorI m x = fromIntegral m <= x\n               menor  x m = x < fromIntegral m\n\n-- 3\u00aa definici\u00f3n (con until sin auxiliares):\nsuelo3 :: Float -> Integer\nsuelo3 x | x < 0     = until ((<=x) . fromIntegral) (subtract 1) (-1)\n         | otherwise = until ((x<)  . fromIntegral) (+1) 1 - 1\n\n-- 4\u00aa definici\u00f3n (con show, read y takeWhile):\nsuelo4 :: Float -> Integer\nsuelo4 x | r < 0     = n-1 \n         | otherwise = n\n    where n = read (takeWhile (\/='.') (show x))\n          r = x - fromIntegral n\n   \n-- 5\u00aa definici\u00f3n (con properFraction):\nsuelo5 :: Float -> Integer\nsuelo5 x = if r < 0 then n-1 else n\n    where (n,r) = properFraction x\n\n-- 6\u00aa definici\u00f3n (por b\u00fasqueda binaria):\nsuelo6 :: Float -> Integer\nsuelo6 x = fst (until unitario (mejora x) (acota x))\n    where inferior x     = until (`menorI` x) (*2) (-1)\n          superior x     = until (x `menor`) (*2) 1\n          menorI m x     = fromIntegral m <= x\n          menor  x m     = x < fromIntegral m\n          acota x        = (inferior x, superior x)\n          mejora x (m,n) = if p `menorI` x then (p,n) else (m,p)\n                           where p =(m+n) `div` 2\n          unitario (m,n) = (m+1 == n)\n\n-- La propiedad es\nprop_suelo x =\n    suelo1 x == y &#038;&#038;\n    suelo2 x == y &#038;&#038;\n    suelo3 x == y &#038;&#038;\n    suelo4 x == y &#038;&#038;\n    suelo5 x == y &#038;&#038;\n    suelo6 x == y\n    where y = floor x\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_suelo\n--    +++ OK, passed 100 tests.\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>La funci\u00f3n suelo asigna a cada n\u00famero real el n\u00famero entero m\u00e1s pr\u00f3ximo por defecto; es decir, el mayor n\u00famero entero igual o menor que ese n\u00famero real. Por ejemplo, al -2.4 le asigna el -3 y al 1.7 el 1. Haskell tiene una implementaci\u00f3n de la funci\u00f3n suelo llamada floor. El objetivo de este&#8230;<\/p>\n","protected":false},"author":1,"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":[5],"tags":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/892"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/comments?post=892"}],"version-history":[{"count":4,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/892\/revisions"}],"predecessor-version":[{"id":1382,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/892\/revisions\/1382"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=892"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=892"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=892"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}