Menu Close

Números con dígitos 1 y 2

Definir las funciones

   numerosCon1y2               :: Int -> [Int]
   restosNumerosCon1y2         :: Int -> [Int]
   grafica_restosNumerosCon1y2 :: Int -> IO ()

tales que

  • (numerosCon1y2 n) es la lista ordenada de números de n dígitos que se pueden formar con los dígitos 1 y 2. Por ejemplo,
     numerosCon1y2 2  ==  [11,12,21,22] 
     numerosCon1y2 3  ==  [111,112,121,122,211,212,221,222]
  • (restosNumerosCon1y2 n) es la lista de los restos de dividir los elementos de (restosNumerosCon1y2 n) entre 2^n. Por ejemplo,
     restosNumerosCon1y2 2 == [3,0,1,2]
     restosNumerosCon1y2 3 == [7,0,1,2,3,4,5,6]
     restosNumerosCon1y2 4 == [7,8,1,2,11,12,5,6,15,0,9,10,3,4,13,14]
  • (graficaRestosNumerosCon1y2 n) dibuja la gráfica de los restos de dividir los elementos de (restosNumerosCon1y2 n) entre 2^n. Por ejemplo, (graficaRestosNumerosCon1y2 3) dibuja

(graficaRestosNumerosCon1y2 4) dibuja

y (graficaRestosNumerosCon1y2 5) dibuja

Nota: En la definición usar la función plotListStyle y como su segundo argumento (el PloStyle) usar

     (defaultStyle {plotType = LinesPoints,
                    lineSpec = CustomStyle [PointType 7]})

Comprobar con QuickCheck que todos los elementos de (restosNumerosCon1y2 n) son distintos.

Soluciones

import Test.QuickCheck
import Graphics.Gnuplot.Simple
 
-- Definición de numerosCon1y2
-- ===========================
 
numerosCon1y2 :: Int -> [Int]
numerosCon1y2 = map digitosAnumero . digitos
 
-- (dígitos n) es la lista ordenada de de listas de n elementos que
-- se pueden formar con los dígitos 1 y 2. Por ejemplo,
--    λ> digitos 2
--    [[1,1],[1,2],[2,1],[2,2]]
--    λ> digitos 3
--    [[1,1,1],[1,1,2],[1,2,1],[1,2,2],[2,1,1],[2,1,2],[2,2,1],[2,2,2]]
digitos :: Int -> [[Int]]
digitos 0 = [[]]
digitos n = map (1:) xss ++ map (2:) xss
  where xss = digitos (n-1)
 
-- (digitosAnumero ds) es el número cuyos dígitos son ds. Por ejemplo,
--    digitosAnumero [2,0,1,9]  ==  2019
digitosAnumero :: [Int] -> Int
digitosAnumero = read . concatMap show
 
-- Definición de restosNumerosCon1y2
-- =================================
 
restosNumerosCon1y2 :: Int -> [Int]
restosNumerosCon1y2 n =
  [x `mod` m | x <- numerosCon1y2 n]
  where m = 2^n
 
-- Definición de graficaRestosNumerosCon1y2
-- =========================================
 
graficaRestosNumerosCon1y2 :: Int -> IO ()
graficaRestosNumerosCon1y2 n =
  plotListStyle
    [ Key Nothing
    , PNG ("Numeros_con_digitos_1_y_2_" ++ show n ++ ".png")
    ]
    (defaultStyle {plotType = LinesPoints,
                   lineSpec = CustomStyle [PointType 7]})
    (restosNumerosCon1y2 n)
 
-- Propiedad de restosNumerosCon1y2
-- ================================
 
-- La propiedad
prop_restosNumerosCon1y2 :: Positive Int -> Bool
prop_restosNumerosCon1y2 (Positive n) =
  todosDistintos (restosNumerosCon1y2 n)
  where todosDistintos xs = xs == nub xs
 
-- La comprobación es
--    λ> quickCheckWith (stdArgs {maxSize=12}) prop_restosNumerosCon1y2
--    +++ OK, passed 100 tests.

Pensamiento

¿Para qué llamar caminos
a los surcos del azar? …
Todo el que camina anda,
como Jesús, sobre el mar.

Antonio Machado

4 soluciones de “Números con dígitos 1 y 2

  1. frahidzam
    import Control.Monad (replicateM)
    import Data.List (nub)
    import Graphics.Gnuplot.Simple
    import Test.QuickCheck
     
    numerosCon1y2 :: Int -> [Int]
    numerosCon1y2 n
      | n <= 0    = []
      | otherwise = map aEntero (replicateM n [1,2])
     
    aEntero :: [Integer] -> Int
    aEntero xs =
      sum [fromIntegral (a*10^b) | (a,b) <- zip (reverse xs) [0..]]
     
    restosNumerosCon1y2 :: Int -> [Int]
    restosNumerosCon1y2 n =
      map (x -> mod x (2^n)) (numerosCon1y2 n)
     
    grafica_numerosCon1y2 :: Int -> IO ()
    grafica_numerosCon1y2 n =
      plotListStyle [ Key Nothing
                    , PNG "restos_Numeros_Con_1_y_2.png"]
                    (defaultStyle { plotType = LinesPoints
                                  , lineSpec = CustomStyle [PointType 7]})
      (numerosCon1y2 n)
     
    prop_restosNumerosCon1y2 :: Int -> Property
    prop_restosNumerosCon1y2 n = n >= 0 ==> nub zs == zs
       where zs = restosNumerosCon1y2 n
     
    -- La comprobación es
    --    λ> quickCheckWith (stdArgs {maxSize=12}) prop_restosNumerosCon1y2
    --    +++ OK, passed 100 tests.
  2. berarcmat
    import Data.List (nub, permutations, sort)
    import Graphics.Gnuplot.Simple
     
    numerosCon1y2 :: Int -> [Int]
    numerosCon1y2 n = sort (nub (map listaNumero (aux 0)))
      where
        aux i
          | i < n =     permutations (take i [1,1..] ++ take (n-i) [2,2..]) ++ aux (i+1)
          | otherwise = permutations (take n [1,1..])  
     
    listaNumero :: [Int] -> Int
    listaNumero [x]    = x
    listaNumero (x:xs) = x + 10 * listaNumero xs
     
    restosNumerosCon1y2 :: Int -> [Int]
    restosNumerosCon1y2 n = map (`rem` (2^n)) (numerosCon1y2 n)
     
    grafica_restosNumerosCon1y2 :: Int -> IO ()
    grafica_restosNumerosCon1y2 n =
      plotListStyle [ Key Nothing
                    , PNG "restos_Numeros_Con_1_y_2.png"]
                    (defaultStyle { plotType = LinesPoints
                                  , lineSpec = CustomStyle [PointType 7]})
                    (restosNumerosCon1y2 n)
  3. luipromor
    import Graphics.Gnuplot.Simple
    import Test.QuickCheck
    import Data.List (nub)
     
    numerosCon1y2 :: Int -> [Int]
    numerosCon1y2 0 = []
    numerosCon1y2 n = [x | x <- [10^(n-1)..10^n], aux x]
      where aux x = and [elem y "12" | y <- show x ]
     
    restosNumerosCon1y2 :: Int -> [Int]
    restosNumerosCon1y2 n =
      [mod x (2^n) | x <- numerosCon1y2 n]
     
    grafica_restosNumerosCon1y2 :: Int -> IO ()
    grafica_restosNumerosCon1y2 n =
      plotListStyle [ Key Nothing
                    , PNG "restos_Numeros_Con_1_y_2.png"]
                    (defaultStyle { plotType = LinesPoints
                                  , lineSpec = CustomStyle [PointType 7]})
                    (restosNumerosCon1y2 n )
     
    prop_numerosCon1y2 :: Int -> Property  
    prop_numerosCon1y2 n =
      n >= 1 ==> nub (numerosCon1y2 n) == numerosCon1y2 n
  4. adogargon
    import Test.QuickCheck
    import Graphics.Gnuplot.Simple
     
    numerosCon1y2 :: Int -> [Int]
    numerosCon1y2 n =
      [x | x <- filter compuesto [1..10^n]
         , length (digitos x) == n]
     
    digitos :: Int -> [Int]
    digitos x = [read [y] |y <- show x ]
     
    compuesto :: Int -> Bool
    compuesto x = all (`elem`[1,2]) (digitos x)
     
    restosNumerosCon1y2 :: Int -> [Int]
    restosNumerosCon1y2 n =
      map (`mod` (2^n)) (numerosCon1y2 n)
     
    prop :: [Int] -> Bool
    prop []     = True
    prop (x:xs) = all (/=x) xs && prop xs
     
    comprobacion :: Int -> Property
    comprobacion n = n >= 1 ==> prop (numerosCon1y2 n)
     
    grafica_restosNumerosCon1y2 :: Int -> IO ()
    grafica_restosNumerosCon1y2 n =
      plotListStyle [ Key Nothing
                    , PNG "restos_Numeros_Con_1_y_2.png"]
                    (defaultStyle { plotType = LinesPoints
                                  , lineSpec = CustomStyle [PointType 7]})
                    (restosNumerosCon1y2 n)

Escribe tu solución

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.