Menor prefijo con suma positiva
Definir la función
menorPrefijoSumaPositiva1 :: [[Int]] -> Maybe [[Int]]
tal que (menorPrefijoSumaPositiva1 xss) es justamente el menor prejijo de xss tal que la suma de lsas sumas de sus elementos es positivo y es Nothing si tal prefijo no existe. Por ejemplo,
menorPrefijoSumaPositiva [[1],[-3],[2,4]] == Just [[1]] menorPrefijoSumaPositiva [[-2,1],[-3],[2,4]] == Just [[-2,1],[-3],[2,4]] menorPrefijoSumaPositiva [[-2,1],[3],[2,4]] == Just [[-2,1],[3]] menorPrefijoSumaPositiva [[-2,1],[-3],[2,-4]] == Nothing menorPrefijoSumaPositiva [[-k..k] | k <- [1..5000]] == Nothing fmap length (menorPrefijoSumaPositiva [[-3000..k] | k <- [0..]]) == Just 5198
Soluciones
import Data.List (inits) import Data.Maybe (listToMaybe) import Test.QuickCheck -- 1ª solución -- =========== menorPrefijoSumaPositiva1 :: [[Int]] -> Maybe [[Int]] menorPrefijoSumaPositiva1 xss = listToMaybe [xs | xs <- tail (inits xss), sum (concat xs) > 0] -- 2ª solución -- =========== menorPrefijoSumaPositiva2 :: [[Int]] -> Maybe [[Int]] menorPrefijoSumaPositiva2 xss = aux [] xss where aux yss _ | sum (concat yss) > 0 = Just (reverse yss) aux _ [] = Nothing aux yss (zs:zss) = aux (zs : yss) zss -- 3ª solución -- =========== menorPrefijoSumaPositiva3 :: [[Int]] -> Maybe [[Int]] menorPrefijoSumaPositiva3 xss = aux (0,[]) (zip (map sum xss) xss) where aux (s,yss) _ | s > 0 = Just (reverse yss) aux _ [] = Nothing aux (s,yss) ((t,zs):zss) = aux (s+t,zs:yss) zss -- Comprobación de equivalencia -- ============================ -- La propiedad es prop_equivalencia :: [[Int]] -> Bool prop_equivalencia xss = all (== (menorPrefijoSumaPositiva1 xss)) [ menorPrefijoSumaPositiva2 xss, menorPrefijoSumaPositiva3 xss ] -- La comprobación es -- λ> quickCheck prop_equivalencia -- +++ OK, passed 100 tests. -- Comparación de eficiencia -- ========================= -- -- La comparación es -- λ> fmap length (menorPrefijoSumaPositiva1 [[-200..k] | k <- [0..]]) -- Just 348 -- (2.40 secs, 2,801,967,392 bytes) -- λ> fmap length (menorPrefijoSumaPositiva2 [[-200..k] | k <- [0..]]) -- Just 348 -- (2.46 secs, 2,800,717,720 bytes) -- λ> fmap length (menorPrefijoSumaPositiva3 [[-200..k] | k <- [0..]]) -- Just 348 -- (0.01 secs, 18,128,464 bytes) -- λ> menorPrefijoSumaPositiva1 [[-k..k] | k <- [1..500]] -- Nothing -- (6.39 secs, 6,127,124,136 bytes) -- λ> menorPrefijoSumaPositiva2 [[-k..k] | k <- [1..500]] -- Nothing -- (6.47 secs, 6,124,201,288 bytes) -- λ> menorPrefijoSumaPositiva3 [[-k..k] | k <- [1..500]] -- Nothing -- (0.03 secs, 37,944,760 bytes)