{"id":6972,"date":"2022-04-25T10:12:10","date_gmt":"2022-04-25T08:12:10","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=6972"},"modified":"2022-05-01T11:15:09","modified_gmt":"2022-05-01T09:15:09","slug":"representacion-de-zeckendorf","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/representacion-de-zeckendorf\/","title":{"rendered":"Representaci\u00f3n de Zeckendorf"},"content":{"rendered":"<p>Los primeros n\u00fameros de Fibonacci son<\/p>\n<pre lang=\"text\">\n   1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, ...\n<\/pre>\n<p>tales que los dos primeros son iguales a 1 y los siguientes se obtienen sumando los dos anteriores.<\/p>\n<p>El <a href=\"https:\/\/bit.ly\/3k5NNt1\">teorema de Zeckendorf<\/a> establece que todo entero positivo n se puede representar, de manera \u00fanica, como la suma de n\u00fameros de Fibonacci no consecutivos decrecientes. Dicha suma se llama la representaci\u00f3n de Zeckendorf de n. Por ejemplo, la representaci\u00f3n de Zeckendorf de 100 es<\/p>\n<pre lang=\"text\">\n   100 = 89 + 8 + 3\n<\/pre>\n<p>Hay otras formas de representar 100 como sumas de n\u00fameros de Fibonacci; por ejemplo,<\/p>\n<pre lang=\"text\">\n   100 = 89 +  8 + 2 + 1\n   100 = 55 + 34 + 8 + 3\n<\/pre>\n<p>pero no son representaciones de Zeckendorf porque 1 y 2 son n\u00fameros de Fibonacci consecutivos, al igual que 34 y 55.<\/p>\n<p>Definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   zeckendorf :: Integer -> [Integer]\n<\/pre>\n<p>tal que <code>(zeckendorf n)<\/code> es la representaci\u00f3n de Zeckendorf de <code>n<\/code>. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   zeckendorf 100 == [89,8,3]\n   zeckendorf 200 == [144,55,1]\n   zeckendorf 300 == [233,55,8,3,1]\n   length (zeckendorf (10^50000)) == 66097\n<\/pre>\n<h4>Soluciones<\/h4>\n<pre lang=\"haskell\">\nmodule Representacion_de_Zeckendorf where\n\nimport Data.List (subsequences)\nimport Test.QuickCheck\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n\nzeckendorf1 :: Integer -> [Integer]\nzeckendorf1 = head . zeckendorf1Aux\n\nzeckendorf1Aux :: Integer -> [[Integer]]\nzeckendorf1Aux n =\n  [xs | xs <- subsequences (reverse (takeWhile (<= n) (tail fibs))),\n        sum xs == n,\n        sinFibonacciConsecutivos xs]\n\n-- fibs es la la sucesi\u00f3n de los n\u00fameros de Fibonacci. Por ejemplo,\n--    take 14 fibs  == [1,1,2,3,5,8,13,21,34,55,89,144,233,377]\nfibs :: [Integer]\nfibs = 1 : scanl (+) 1 fibs\n-- (sinFibonacciConsecutivos xs) se verifica si en la sucesi\u00f3n\n-- decreciente de n\u00famero de Fibonacci xs no hay dos consecutivos. Por\n-- ejemplo, \n\n-- (sinFibonacciConsecutivos xs) se verifica si en la sucesi\u00f3n\n-- decreciente de n\u00famero de Fibonacci xs no hay dos consecutivos. Por\n-- ejemplo, \n--    sinFibonacciConsecutivos [89, 8, 3]      ==  True\n--    sinFibonacciConsecutivos [55, 34, 8, 3]  ==  False\nsinFibonacciConsecutivos :: [Integer] -> Bool\nsinFibonacciConsecutivos xs =\n  and [x \/= siguienteFibonacci y | (x,y) <- zip xs (tail xs)]\n\n-- (siguienteFibonacci n) es el menor n\u00famero de Fibonacci mayor que\n-- n. Por ejemplo, \n--    siguienteFibonacci 34  ==  55\nsiguienteFibonacci :: Integer -> Integer\nsiguienteFibonacci n =\n  head (dropWhile (<= n) fibs)\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n\nzeckendorf2 :: Integer -> [Integer]\nzeckendorf2 = head . zeckendorf2Aux\n\nzeckendorf2Aux :: Integer -> [[Integer]]\nzeckendorf2Aux n = map reverse (aux n (tail fibs))\n  where aux 0 _ = [[]]\n        aux m (x:y:zs)\n            | x <= m     = [x:xs | xs <- aux (m-x) zs] ++ aux m (y:zs)\n            | otherwise  = []\n\n-- 3\u00aa soluci\u00f3n\n-- ===========\n\nzeckendorf3 :: Integer -> [Integer]\nzeckendorf3 0 = []\nzeckendorf3 n = x : zeckendorf3 (n - x)\n  where x = last (takeWhile (<= n) fibs)\n\n-- 4\u00aa soluci\u00f3n\n-- ===========\n\nzeckendorf4 :: Integer -> [Integer]\nzeckendorf4 n = aux n (reverse (takeWhile (<= n) fibs))\n  where aux 0 _      = []\n        aux m (x:xs) = x : aux (m-x) (dropWhile (>m-x) xs)\n\n-- Comprobaci\u00f3n de equivalencia\n-- ============================\n\n-- La propiedad es\nprop_zeckendorf :: Positive Integer -> Bool\nprop_zeckendorf (Positive n) =\n  all (== zeckendorf1 n)\n      [zeckendorf2 n,\n       zeckendorf3 n,\n       zeckendorf4 n]\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck prop_zeckendorf\n--    +++ OK, passed 100 tests.\n\n-- Comparaci\u00f3n de eficiencia\n-- =========================\n\n-- La comparaci\u00f3n es\n--    \u03bb> zeckendorf1 (7*10^4)\n--    [46368,17711,4181,1597,89,34,13,5,2]\n--    (1.49 secs, 2,380,707,744 bytes)\n--    \u03bb> zeckendorf2 (7*10^4)\n--    [46368,17711,4181,1597,89,34,13,5,2]\n--    (0.07 secs, 21,532,008 bytes)\n--\n--    \u03bb> zeckendorf2 (10^6)\n--    [832040,121393,46368,144,55]\n--    (1.40 secs, 762,413,432 bytes)\n--    \u03bb> zeckendorf3 (10^6)\n--    [832040,121393,46368,144,55]\n--    (0.01 secs, 542,488 bytes)\n--    \u03bb> zeckendorf4 (10^6)\n--    [832040,121393,46368,144,55]\n--    (0.01 secs, 536,424 bytes)\n--\n--    \u03bb> length (zeckendorf3 (10^3000))\n--    3947\n--    (3.02 secs, 1,611,966,408 bytes)\n--    \u03bb> length (zeckendorf4 (10^2000))\n--    2611\n--    (0.02 secs, 10,434,336 bytes)\n--\n--    \u03bb> length (zeckendorf4 (10^50000))\n--    66097\n--    (2.84 secs, 3,976,483,760 bytes)\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium\/blob\/main\/src\/Representacion_de_Zeckendorf.hs\">GitHub<\/a>.<\/p>\n<p>La elaboraci\u00f3n de las soluciones se describe en el siguiente v\u00eddeo<\/p>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/U-nBf1WnLTw\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Los primeros n\u00fameros de Fibonacci son 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, &#8230; tales que los dos primeros son iguales a 1 y los siguientes se obtienen sumando los dos anteriores. El teorema de Zeckendorf establece que todo entero positivo n se puede representar, de manera \u00fanica, como&#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":[2],"tags":[41,100,8,498,59,71,134,415,11,557,32,78,88,40,45,34,521,146,9],"jetpack_featured_media_url":"","jetpack_sharing_enabled":false,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6972"}],"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=6972"}],"version-history":[{"count":4,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6972\/revisions"}],"predecessor-version":[{"id":6991,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/6972\/revisions\/6991"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=6972"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=6972"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=6972"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}