Menu Close

Ofertas 3 por 2

En una tienda tiene la “oferta 3 por 2” de forma que cada cliente que elige 3 artículos obtiene el más barato de forma gratuita. Por ejemplo, si los precios de los artículos elegidos por un cliente son 10, 2, 4, 5 euros pagará 19 euros si agrupa los artículos en (10,2,4) y (5) o pagará 17 si lo agupa en (5,10,4) y (2).

Definir la función

   minimoConOferta :: [Int] -> Int

tal que (minimoConOferta xs) es lo mínimo que pagará el cliente si los precios de la compra son xs; es decir, lo que pagará agrupando los artículos de forma óptima para aplicar la oferta 3 por 2. Por ejemplo,

   minimoConOferta [10,2,4,5]     ==  17
   minimoConOferta [3,2,3,2]      ==  8
   minimoConOferta [6,4,5,5,5,5]  ==  21

Soluciones

import Data.List ( sort
                 , sortOn)
import Data.Ord  ( Down(..))
 
-- 1ª solución
-- ===========
 
minimoConOferta :: [Int] -> Int
minimoConOferta xs = sum (sinTerceros (reverse (sort xs)))
 
sinTerceros :: [a] -> [a]
sinTerceros []         = []
sinTerceros [x]        = [x]
sinTerceros [x,y]      = [x,y]
sinTerceros (x:y:_:zs) = x : y : sinTerceros zs
 
-- 2ª solución
-- ===========
 
minimoConOferta2 :: [Int] -> Int
minimoConOferta2 = sum . sinTerceros . reverse . sort
 
-- 3ª solución
-- ===========
 
minimoConOferta3 :: [Int] -> Int
minimoConOferta3 = sum . sinTerceros . sortOn Down
 
-- 4ª solución
-- ===========
 
minimoConOferta4 :: [Int] -> Int
minimoConOferta4 xs = aux (reverse (sort xs)) 0
  where aux (a:b:_:ds) n = aux ds (a+b+n)
        aux as         n = n + sum as 
 
-- 5ª solución
-- ===========
 
minimoConOferta5 :: [Int] -> Int
minimoConOferta5 xs = aux (sortOn Down xs) 0
  where aux (a:b:_:ds) n = aux ds (a+b+n)
        aux as         n = n + sum as

Pensamiento

Despacito y buena letra:
el hacer las cosas bien
importa más que el hacerlas.

Antonio Machado

Medio

6 soluciones de “Ofertas 3 por 2

  1. frahidzam
    import Data.List (sort)
     
    minimoConOferta :: [Int] -> Int
    minimoConOferta xs = sum (quita3 (reverse (sort xs)))
     
    quita3 :: [Int] -> [Int]
    quita3 []         = []
    quita3 [x]        = [x]
    quita3 [x,y]      = [x,y]
    quita3 (x:y:z:xs) = [x,y] ++ quita3 xs
  2. adogargon
    import Data.List (sort)
     
    minimoConOferta :: [Int] -> Int
    minimoConOferta xs = sum xs - sum (cada3 (reverse (sort xs)))
      where cada3 []         = []
            cada3 [x]        = []
            cada3 [x,y]      = []
            cada3 (x:y:z:xs) = [z] ++ cada3 xs
  3. luipromor
    import Data.List (delete, sort)
     
    minimoConOferta :: [Int] -> Int
    minimoConOferta  = aux . reverse . sort
      where aux [] = 0
            aux xs  | length ys == 3 = (sum . delete (minimum ys)) ys + aux (drop 3 xs)
                    | otherwise      = sum ys
              where ys = take 3 xs
  4. lucsanand
    import Data.List (sort)
     
    minimoConOferta :: [Int] -> Int
    minimoConOferta xs
      | length xs >= 3 = sum zs - minimum zs + minimoConOferta (drop 3 ys)
      | otherwise      = sum xs
      where ys = reverse (sort xs)
            zs = take 3 ys
  5. javmarcha1
    minimoConOferta :: [Int] -> Int
    minimoConOferta xs
      | length xs > 2 = sum ys - minimum ys + minimoConOferta (drop 3 zs)
      | otherwise     = sum xs
      where zs = reverse (sort xs)
            ys = take 3 zs
  6. ireprirod
    import Data.List
     
    minimoConOfertaA6 :: [Int] -> Int
    minimoConOfertaA6 = pagar . agrupaEn3
     
    agrupaEn3 :: [Int] -> [[Int]]
    agrupaEn3 [] = []
    agrupaEn3 xs = take 3 ys : agrupaEn3 (drop 3 ys)
      where ys = reverse (sort xs)
     
    pagar :: [[Int]] -> Int
    pagar xss = sum (map (sum . take 2) xss)

Escribe tu solución

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.