Antiimágenes en una función creciente
Definir la función
1 |
antiimagen :: (Int -> Int) -> Int -> Maybe Int |
tal que (antiimagen f y) es justo el x tal que f(x) = y, si y pertenece a la imagen de la función creciente f, o nada, en caso contrario. Por ejemplo,
1 2 |
antiimagen (^2) 25 == Just 5 antiimagen (^3) 25 == Nothing |
Nota. Se supone que f está definida sobre los números naturales.
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
-- 1ª definición -- ============= antiimagen1 :: (Int -> Int) -> Int -> Maybe Int antiimagen1 f y | estaEnImagen f y = Just x | otherwise = Nothing where x = head [x | x <- [0..], f x == y] -- (estaEnImagen f y) se verifica si pertenece a la imagen de f. Por -- ejemplo, -- estaEnImagen (^2) 25 == True -- estaEnImagen (^2) 30 == False estaEnImagen :: (Int -> Int) -> Int -> Bool estaEnImagen f y = elem y (takeWhile (<=y) (imagen f)) -- (imagen f) es la imagen de f. Por ejemplo, -- take 10 (imagen (^2)) == [0,1,4,9,16,25,36,49,64,81] -- take 10 (imagen (*3)) == [0,3,6,9,12,15,18,21,24,27] imagen :: (Int -> Int) -> [Int] imagen f = map f [0..] -- 2ª definición (con lookup y maxBound) -- ===================================== antiimagen2 :: (Int -> Int) -> Int -> Maybe Int antiimagen2 f y = lookup y (takeWhile (<= (y,maxBound)) [(f x, x) | x <- [0..]]) |
Otra vez usando búsqueda dicotómica sin acotar.
Y ésta es mi versión con búsqueda dicotómica:
La primera definición falla en el primer ejemplo
Muchas gracias por el apunte. Una versión corregida:
Se puede mejorar (lo añado como nueva respuesta).