Ir al contenido principal

Densidad de números no monótonos

Un número entero positivo se dice que es

  • creciente si cada uno de sus dígitos es menor o igual que el que está a su derecha; por ejemplo, 134479.
  • decreciente si cada uno de sus dígitos es menor o igual que el que está a su derecha; por ejemplo, 664210.
  • no monótono si no es creciente ni decreciente; por ejemplo, 155369.

Para cada entero positivo n, la densidad números no monótonos hasta n es el cociente entre la cantidad de n números no monótonos entre menores o iguales que n y el número n. Por ejemplo, hasta 150 hay 19 números no monótonos (101, 102, 103, 104, 105, 106, 107, 108, 109, 120, 121, 130, 131, 132, 140, 141, 142, 143 y 150); por tanto, la densidad hasta 150 es 19/150 = 0.12666667

Definir las siguientes funciones

densidad              :: Integer -> Float
menorConDensidadMayor :: Float -> Integer

tales que

  • (densidad n) es la densidad de números no monótonos hasta n. Por ejemplo,
densidad 100  ==  0.0
densidad 200  ==  0.265
densidad 400  ==  0.4375
densidad 800  ==  0.53375
  • (menorConDensidadMayor x) es el menor número n tal que la densidad de números no monótonos hasta n es mayor o igual que x. Por ejemplo,
menorConDensidadMayor 0.5   ==  538
densidad 537                ==  0.49906892
densidad 538                ==  0.5
menorConDensidadMayor 0.9   ==  21780
densidad 21779              ==  0.8999954
densidad 21780              ==  0.9
menorConDensidadMayor 0.99  ==  1586996

Soluciones

import Data.List (genericLength, sort)

-- 1ª definición
-- =============

densidad :: Integer -> Float
densidad n =
    genericLength [x | x <- [1..n], esNoMonotono x] / fromIntegral n

esNoMonotono :: Integer -> Bool
esNoMonotono x = not (esCreciente x) && not (esDecreciente x)

esCreciente :: Integer -> Bool
esCreciente x = show x == sort (show x)

esDecreciente :: Integer -> Bool
esDecreciente x = reverse (show x) == sort (show x)

menorConDensidadMayor :: Float -> Integer
menorConDensidadMayor x  =
    buscaProporcion x (filter esNoMonotono [1..])
    where buscaProporcion x =
              snd . head . filter condicion . zip [1..]
              where condicion (a,b) = a >= x * fromIntegral b