import Data.List (inits)
-- 1ª solución
-- ===========
mayorPrefijoAcotado :: [Int] -> Int -> [Int]
mayorPrefijoAcotado [] _ = []
mayorPrefijoAcotado (x:xs) y
| x > y = []
| otherwise = x : mayorPrefijoAcotado xs (y-x)
-- 2ª solución
-- ===========
mayorPrefijoAcotado2 :: [Int] -> Int -> [Int]
mayorPrefijoAcotado2 xs y =
take (longitudMayorPrefijoAcotado2 xs y) xs
longitudMayorPrefijoAcotado2 :: [Int] -> Int -> Int
longitudMayorPrefijoAcotado2 xs y =
length (takeWhile (<=y) (map sum (inits xs))) - 1
-- 3ª solución
-- ===========
mayorPrefijoAcotado3 :: [Int] -> Int -> [Int]
mayorPrefijoAcotado3 xs y =
take (longitudMayorPrefijoAcotado3 xs y) xs
longitudMayorPrefijoAcotado3 :: [Int] -> Int -> Int
longitudMayorPrefijoAcotado3 xs y =
length (takeWhile (<= y) (scanl1 (+) xs))
-- Equivalencia
-- ============
-- La propiedad es
prop_equiv :: [Int] -> Int -> Bool
prop_equiv xs y =
mayorPrefijoAcotado xs' y' == mayorPrefijoAcotado2 xs' y' &&
mayorPrefijoAcotado xs' y' == mayorPrefijoAcotado3 xs' y'
where xs' = map abs xs
y' = abs y
-- La comprobación es
-- λ> quickCheck prop_equiv
-- +++ OK, passed 100 tests.
-- (0.01 secs, 2,463,688 bytes)
-- Comparación de eficiencia
-- =========================
-- λ> length (mayorPrefijoAcotado (repeat 1) (2*10^4))
-- 20000
-- (0.04 secs, 5,086,544 bytes)
-- λ> length (mayorPrefijoAcotado2 (repeat 1) (2*10^4))
-- 20000
-- (11.22 secs, 27,083,980,168 bytes)
-- λ> length (mayorPrefijoAcotado3 (repeat 1) (2*10^4))
-- 20000
-- (0.02 secs, 4,768,992 bytes)
--
-- λ> length (mayorPrefijoAcotado (repeat 1) (8*10^6))
-- 8000000
-- (3.19 secs, 1,984,129,832 bytes)
-- λ> length (mayorPrefijoAcotado3 (repeat 1) (8*10^6))
-- 8000000
-- (1.02 secs, 1,856,130,936 bytes)