Definir la función
divisionEquitativa :: [Int] -> Maybe ([Int],[Int]) |
divisionEquitativa :: [Int] -> Maybe ([Int],[Int])
tal que (divisionEquitativa xs) determina si la lista de números enteros positivos xs se puede dividir en dos partes (sin reordenar sus elementos) con la misma suma. Si es posible, su valor es el par formado por las dos partes. Si no lo es, su valor es Nothing. Por ejemplo,
divisionEquitativa [1,2,3,4,5,15] == Just ([1,2,3,4,5],[15])
divisionEquitativa [15,1,2,3,4,5] == Just ([15],[1,2,3,4,5])
divisionEquitativa [1,2,3,4,7,15] == Nothing
divisionEquitativa [1,2,3,4,15,5] == Nothing |
divisionEquitativa [1,2,3,4,5,15] == Just ([1,2,3,4,5],[15])
divisionEquitativa [15,1,2,3,4,5] == Just ([15],[1,2,3,4,5])
divisionEquitativa [1,2,3,4,7,15] == Nothing
divisionEquitativa [1,2,3,4,15,5] == Nothing
Soluciones
import Data.Maybe (isNothing, fromJust, listToMaybe)
import Data.List (elemIndex, inits, tails)
-- 1ª solución
divisionEquitativa1 :: [Int] -> Maybe ([Int],[Int])
divisionEquitativa1 xs = aux (particiones xs)
where aux [] = Nothing
aux ((as,bs):ys) | sum as == sum bs = Just (as,bs)
| otherwise = aux ys
particiones xs = [splitAt i xs | i <- [1..length xs-1]]
-- 2ª solución
divisionEquitativa2 :: [Int] -> Maybe ([Int],[Int])
divisionEquitativa2 xs
| 2 * b == suma = Just $ splitAt (length as + 1) xs
| otherwise = Nothing
where suma = sum xs
(as,(b:bs)) = span (<suma `div` 2) $ scanl1 (+) xs
-- 3ª solución
divisionEquitativa3 :: [Int] -> Maybe ([Int],[Int])
divisionEquitativa3 xs
| odd n = Nothing
| isNothing p = Nothing
| otherwise = Just (splitAt (1 + fromJust p) xs)
where n = sum xs
ys = scanl1 (+) xs
p = elemIndex (n `div` 2) ys
-- 4ª solución
divisionEquitativa4 :: [Int] -> Maybe ([Int],[Int])
divisionEquitativa4 xs
| odd (sum xs) = Nothing
| otherwise = aux [] xs
where aux as bs@(b:bs') | sum as == sum bs = Just (reverse as, bs)
| sum as > sum bs = Nothing
| otherwise = aux (b:as) (bs')
-- 5ª solución
divisionEquitativa5 :: [Int] -> Maybe ([Int],[Int])
divisionEquitativa5 xs =
listToMaybe
[(ys, zs) | (ys,zs) <- zip (inits xs) (tails xs)
, sum ys == sum zs ] |
import Data.Maybe (isNothing, fromJust, listToMaybe)
import Data.List (elemIndex, inits, tails)
-- 1ª solución
divisionEquitativa1 :: [Int] -> Maybe ([Int],[Int])
divisionEquitativa1 xs = aux (particiones xs)
where aux [] = Nothing
aux ((as,bs):ys) | sum as == sum bs = Just (as,bs)
| otherwise = aux ys
particiones xs = [splitAt i xs | i <- [1..length xs-1]]
-- 2ª solución
divisionEquitativa2 :: [Int] -> Maybe ([Int],[Int])
divisionEquitativa2 xs
| 2 * b == suma = Just $ splitAt (length as + 1) xs
| otherwise = Nothing
where suma = sum xs
(as,(b:bs)) = span (<suma `div` 2) $ scanl1 (+) xs
-- 3ª solución
divisionEquitativa3 :: [Int] -> Maybe ([Int],[Int])
divisionEquitativa3 xs
| odd n = Nothing
| isNothing p = Nothing
| otherwise = Just (splitAt (1 + fromJust p) xs)
where n = sum xs
ys = scanl1 (+) xs
p = elemIndex (n `div` 2) ys
-- 4ª solución
divisionEquitativa4 :: [Int] -> Maybe ([Int],[Int])
divisionEquitativa4 xs
| odd (sum xs) = Nothing
| otherwise = aux [] xs
where aux as bs@(b:bs') | sum as == sum bs = Just (reverse as, bs)
| sum as > sum bs = Nothing
| otherwise = aux (b:as) (bs')
-- 5ª solución
divisionEquitativa5 :: [Int] -> Maybe ([Int],[Int])
divisionEquitativa5 xs =
listToMaybe
[(ys, zs) | (ys,zs) <- zip (inits xs) (tails xs)
, sum ys == sum zs ]