Home » Calculate Cheapest Bottle Combination

Calculate Cheapest Bottle Combination

Today’s challenge is contributed by Mehmet Çiçek. Have you ever been facing of this issue when purchasing something: “What is the best choice at lowest cost?” There are 5 kind of bottles with different capacity (liter) and different cost. The higher capacity, the lower cost. If someone need to buy “n” liters, what the lowest cost should be?

📌 Challenge Details and Links
ExcelBI Excel Challenge Number: 628
Challenge Difficulty: ⭐️⭐️
📥Download Sample File
📥Link to the solutions on LinkedIn

Solving the challenge of Calculate Cheapest Bottle Combination with Excel

Excel solution 1 for Calculate Cheapest Bottle Combination, proposed by Bo Rydobon 🇹🇭:
=MAP(
    A9:A12,
    LAMBDA(
        a,
        MAX(
            REDUCE(
                a*{1,
                0},
                SEQUENCE(
                    9
                ),
                LAMBDA(
                    i,
                    _,
                    LET(
                        c,
                        B2:B6,
                        n,
                        INT(
                            @i/c
                        ),
                        x,
                        XMATCH(
                            1,
                            n,
                            1
                        ),
                        
                        IF(
                            ISNA(
                                x
                            ),
                            i,
                            HSTACK(
                                @i-INDEX(
                                    n*c,
                                    x
                                ),
                                INDEX(
                                    i,
                                    2
                                )+INDEX(
                                    n*C2:C6,
                                    x
                                )
                            )
                        )
                    )
                )
            )
        )
    )
)
Excel solution 2 for Calculate Cheapest Bottle Combination, proposed by Bo Rydobon 🇹🇭:
=MAP(A9:A12,LAMBDA(i,LET(c,TOROW(B2:B6),r,REDUCE(i&" 0",c,LAMBDA(a,i,LET(l,TEXTBEFORE(a," "),n,INT(l/c),UNIQUE(TOCOL(ROUND(l-n*c,2)&" "&n*TOROW(C2:C6)+TEXTAFTER(a," ")))))),
MIN(--FILTER(TEXTAFTER(r," "),TEXTBEFORE(r," ")="0")))))
Excel solution 3 for Calculate Cheapest Bottle Combination, proposed by Bo Rydobon 🇹🇭:
=LET(
    c,
    B2:B6,
    r,
    LAMBDA(
        r,
        i,
        j,
        LET(
            n,
            INT(
                i/c
            ),
            x,
            XMATCH(
                1,
                n,
                1
            ),
            
            IF(
                ROUND(
                    @i,
                    9
                ),
                r(
                    r,
                    i-INDEX(
                        n*c,
                        x
                    ),
                    j+INDEX(
                        n*C2:C6,
                        x
                    )
                ),
                j
            )
        )
    ),
    
    MAP(
        A9:A12,
        LAMBDA(
            a,
            r(
                r,
                a,
                
            )
        )
    )
)
Excel solution 4 for Calculate Cheapest Bottle Combination, proposed by John V.:
=LET(F,LAMBDA(F,v,t,LET(n,(v>0)*MAX(B2,v),c,VLOOKUP(n,B2:C6,{1,2}),e,INT(n/@c),d,t+e*MAX(c),r,ROUND(n-@c*e,2),IF(r,F(F,r,d),d))),MAP(A9:A12,LAMBDA(x,F(F,x,))))
Excel solution 5 for Calculate Cheapest Bottle Combination, proposed by 🇰🇷 Taeyong Shin:
=LET(
    R,
    LAMBDA(
        R,
        i,
        j,
        LET(
            x,
            XLOOKUP(
                0.9,
                i/B2:B6,
                B2:C6,
                0,
                1
            ),
            IF(
                N(
                    x
                ),
                R(
                    R,
                    i-N(
                    x
                ),
                    j+INDEX(
                        x,
                        2
                    )
                ),
                j
            )
        )
    ),
    MAP(
        A9:A12,
        LAMBDA(
            x,
            R(
                R,
                x,
                
            )
        )
    )
)
Excel solution 6 for Calculate Cheapest Bottle Combination, proposed by Kris Jaganah:
=LET(a,
    B2:B6,
    b,
    C2:C6,
    c,
    A9:A12,
    d,
    XLOOKUP(
        c,
        a,
        a,
        ,
        -1
    ),
    e,
    c/d,
    f,
    INT(
        e
    ),
    g,
    d*f,
    h,
    c-g,
    i,
    XLOOKUP(
        h,
        a,
        a,
        0,
        -1
    ),
    (IF(
        h=0,
        0,
        h/i
    )*XLOOKUP(
        i,
        a,
        b,
        0
    ))+(XLOOKUP(
        d,
        a,
        b
    )*f))
Excel solution 7 for Calculate Cheapest Bottle Combination, proposed by Aditya Kumar Darak 🇮🇳:
=LET(
    
     _bottleType,
     A2:C6,
    
     _input,
     A9:A12,
    
     _sort,
     SORT(
         _bottleType,
          2,
          -1
     ),
    
     _rtrn,
     MAP(
         
          _input,
         
          LAMBDA(
              x,
              
               LET(
                   
                    rt,
                    SCAN(
                        
                         x,
                        
                         INDEX(
                             _sort,
                              ,
                              2
                         ),
                        
                         LAMBDA(
                             a,
                              b,
                              MAX(
                                  a - FLOOR.MATH(
                                      a,
                                       b
                                  ),
                                   0
                              )
                         )
                         
                    ),
                   
                    diff,
                    VSTACK(
                        x,
                         DROP(
                             rt,
                              -1
                         )
                    ) - rt,
                   
                    unts,
                    IF(
                        diff,
                         diff / INDEX(
                             _sort,
                              ,
                              2
                         ),
                         0
                    ),
                   
                    amt,
                    unts * TAKE(
                        _sort,
                         ,
                         -1
                    ),
                   
                    rtrn,
                    SUM(
                        amt
                    ),
                   
                    rtrn
                    
               )
               
          )
          
     ),
    
     _rtrn
    
)
Excel solution 8 for Calculate Cheapest Bottle Combination, proposed by Timothée BLIOT:
=MAP(A9:A12,LAMBDA(z,SUM(LET(B,B2:B6,C,C2:C6,XLOOKUP(REDUCE(0,ROW(1:9),LAMBDA(w,v,LET(A,CEILING(z-SUM(w),0.1),VSTACK(w,IF(A=0,0,XLOOKUP(A,B,B,,-1)))))),B,C,0)))))
Excel solution 9 for Calculate Cheapest Bottle Combination, proposed by Hussein SATOUR:
=MAP(
    A9:A12,
    LAMBDA(
        z,
        LET(
            S,
            SORT,
            R,
            ROUNDDOWN,
            L,
            S(
                B2:B6,
                ,
                -1
            ),
            C,
            S(
                C2:C6,
                ,
                -1
            ),
            a,
            DROP(
                SCAN(
                    ,
                    VSTACK(
                        z,
                        L
                    ),
                    LAMBDA(
                        x,
                        y,
                        x-R(
                            x/y,
                            0
                        )*y
                    )
                ),
                -1
            ),
            SUM(
                C*R(
                    a/L,
                    0
                )
            )
        )
    )
)
Excel solution 10 for Calculate Cheapest Bottle Combination, proposed by LEONARD OCHEA 🇷🇴:
=LET(
    m,
    B2:B6,
    n,
    C2:C6,
    F,
    LAMBDA(
        F,
        x,
        a,
        LET(
            y,
            XLOOKUP(
                ROUND(
                    x,
                    1
                ),
                m,
                m,
                ,
                -1
            ),
            b,
            a+XLOOKUP(
                y,
                m,
                n
            ),
            IF(
                x-y>0,
                F(
                    F,
                    x-y,
                    b
                ),
                b
            )
        )
    ),
    MAP(
        A9:A12,
        LAMBDA(
            i,
            F(
                F,
                i,
                0
            )
        )
    )
)
Excel solution 11 for Calculate Cheapest Bottle Combination, proposed by Md. Zohurul Islam:
=LET(
    a,
    B2:B6,
    b,
    C2:C6,
    z,
    A9:A12,
    
    _s1,
    XMATCH(
        z,
        a,
        -1
    ),
    
    d,
    INDEX(
        b,
        _s1
    ),
    
    _s2,
    INT(
        z/XLOOKUP(
            z,
            a,
            a,
            ,
            -1
        )
    ),
    
    e,
    d*_s2,
    
    _s3,
    MOD(
        z,
        INDEX(
            a,
            _s1
        )
    ),
    
    _s4,
    XLOOKUP(
        _s3,
        a,
        a,
        0,
        -1
    ),
    
    _s5,
    IFERROR(
        _s3/_s4,
        0
    ),
    
    _s6,
    XLOOKUP(
        _s4,
        a,
        b,
        0
    ),
    
    f,
    _s5*_s6,
    
    result,
    e+f,
    
    result
)
Excel solution 12 for Calculate Cheapest Bottle Combination, proposed by Pieter de B.:
=LET(
    n,
    INT(
        TOROW(
            A9:A12
        )/B2:B6
    ),
    c,
    CHOOSECOLS,
    s,
    {1,
    2,
    3,
    4,
    5},
    DROP(
        REDUCE(
            "",
            A9:A12,
            LAMBDA(
                x,
                m,
                LET(
                    y,
                    REDUCE(
                        {0,
                        0},
                        s,
                        LAMBDA(
                            a,
                            b,
                            LET(
                                i,
                                c(
                                    n,
                                    b
                                ),
                                j,
                                HSTACK(
                                    TOCOL(
                                        TOROW(
                                            TAKE(
                                                a,
                                                ,
                                                1
                                            )
                                        )+i*c(
                                            C2:C6,
                                            b
                                        )
                                    ),
                                    TOCOL(
                                        TOROW(
                                            TAKE(
                                                a,
                                                ,
                                                -1
                                            )
                                        )+i*c(
                                            B2:B6,
                                            b
                                        )
                                    )
                                ),
                                FILTER(
                                    j,
                                    IFERROR(
                                        DROP(
                                            j,
                                            ,
                                            1
                                        ),
                                        0
                                    )<=m
                                )
                            )
                        )
                    ),
                    VSTACK(
                        x,
                        @SORT(
                            FILTER(
                                y,
                                IFNA(
                                    DROP(
                                        y,
                                        ,
                                        1
                                    ),
                                    0
                                )=m
                            )
                        )
                    )
                )
            )
        ),
        1
    )
)
Excel solution 13 for Calculate Cheapest Bottle Combination, proposed by Pieter de B.:
=DROP(
    REDUCE(
        A9:A12,
        6-SEQUENCE(
            5
        ),
        LAMBDA(
            a,
            b,
            LET(
                i,
                INDEX(
                    B2:B6,
                    b
                ),
                c,
                TAKE(
                    a,
                    ,
                    1
                )/i,
                HSTACK(
                    TAKE(
                    a,
                    ,
                    1
                )-i*INT(
                    c
                ),
                    IFERROR(
                        DROP(
                    a,
                    ,
                    1
                ),
                        0
                    )+INDEX(
                        C2:C6,
                        b
                    )*INT(
                    c
                )
                )
            )
        )
    ),
    ,
    1
)
Excel solution 14 for Calculate Cheapest Bottle Combination, proposed by JvdV -:
=LET(
    x,
    LAMBDA(
        f,
        a,
        b,
        IF(
            a,
            LET(
                c,
                XLOOKUP(
                    a,
                    B2:B6,
                    +B2:C6,
                    ,
                    -1
                ),
                f(
                    f,
                    TRUNC(
                        a-@c,
                        1
                    ),
                    b+MAX(
                        c
                    )
                )
            ),
            b
        )
    ),
    MAP(
        A9:A12,
        LAMBDA(
            s,
            x(
                x,
                s,
                
            )
        )
    )
)

TRUNC is in there because of a floating point issue. Try this in 4 cells in your Excel. Put 2.3 in A1,
     then in A2 put =A1-2,
     in A3 put =A2-0.1 and in A4 put =A3-0.1. Now set it to a 15-digit precision. And you'll see that A4 starts behaving wonky. I think this is what is described in the "near-zero results" section of the article below:

https://learn.microsoft.com/en-us/office/troubleshoot/excel/floating-point-arithmetic-inaccurate-result

EDIT: Solved the "near-zero results" decimal point issue without TRUNC:

=LET(
    x,
    LAMBDA(
        f,
        a,
        b,
        IF(
            a>0,
            LET(
                c,
                XLOOKUP(
                    a,
                    B2:B6,
                    +B2:C6,
                    C2,
                    -1
                ),
                f(
                    f,
                    a-@c,
                    b+MAX(
                        c
                    )
            &    )
            ),
            b
        )
    ),
    MAP(
        A9:A12,
        LAMBDA(
            s,
            x(
                x,
                s,
                
            )
        )
    )
)
Excel solution 15 for Calculate Cheapest Bottle Combination, proposed by Burhan Cesur:
=DROP(REDUCE("",A9:A12,LAMBDA(s,v,VSTACK(s,LET(x,LOOKUP(v,$B$2:$B$6,$B$2:$B$6),QUOTIENT(v,x)*LOOKUP(v,$B$2:$B$6,$C$2:$C$6)+IF(MOD(v,x)=ROUND(MOD(v,x),0),IFNA(LOOKUP(MOD(v,x),$B$2:$B$6,$C$2:$C$6),0),(MOD(v,x)*10)*IFNA(LOOKUP(MOD(v,x),$B$2:$B$6,$C$2:$C$6),0)))))),1)
Excel solution 16 for Calculate Cheapest Bottle Combination, proposed by Burhan Cesur:
=DROP(REDUCE("",A9:A12,LAMBDA(s,v,VSTACK(s,LET(
 hedef,v,
 fx, LAMBDA(fx,kalan,birikim,
 IF(
 kalan <= 0,
 birikim,
 LET(
 uygun, IFERROR(FILTER(B2:B6, B2:B6 <= kalan, ""), 0),
 en_uygun, IFERROR(IF(kalan<1,IF(ISNUMBER(FILTER(B2:B6,B2:B6=(kalan-MAX(uygun)))),MAX(uygun),MIN(uygun)),MAX(uygun)), 0),
 fiyat, IF(en_uygun = 0, 0, INDEX(C2:C6, MATCH(en_uygun, B2:B6, 0))),
 yeni_kalan, kalan - en_uygun,
 yeni_uygun, IFERROR(FILTER(B2:B6, B2:B6 <= yeni_kalan, ""), 0),
 IF(
 OR(ROWS(uygun) = 0, en_uygun = 0),
 birikim,
 IF(
 ROWS(yeni_uygun) = 0,
 fx(fx, kalan - MIN(uygun), VSTACK(birikim, HSTACK(MIN(uygun), INDEX(C2:C6, MATCH(MIN(uygun), B2:B6, 0))))),
 fx(fx, yeni_kalan, SUM(VSTACK(birikim, fiyat)))
 )
 )
 )
 )
 ),
 fx(fx, hedef, "")
)))),1)
Excel solution 17 for Calculate Cheapest Bottle Combination, proposed by Mehmet Çiçek:
=MAP(
    A9:A12,
    LAMBDA(
        x,
        LET(
            b,
            B2:B6,
            i,
            VLOOKUP(
                x,
                b,
                1
            ),
            SUM(
                IFERROR(
                    LOOKUP(
                        --MID(
                            REPT(
                                i,
                                INT(
                                    x/i
                                )
                            )&MOD(
                                x,
                                i
                            ),
                            SEQUENCE(
                                10
                            ),
                            1
                        ),
                        b,
                        C2:C6
                    ),
                    0
                )
            )
        )
    )
)

Solving the challenge of Calculate Cheapest Bottle Combination with Python in Excel

Python in Excel solution 1 for Calculate Cheapest Bottle Combination, proposed by Aditya Kumar Darak 🇮🇳:
import math
df = xl("A1:C6", True)
qtys = xl("A8:A12", True)
df.columns = ["Bottle", "Capacity", "Cost"]
sort = df.sort_values(by="Capacity", ascending=False)
def MyFun(qty):
 btl = [
 [
 bottle := math.floor(qty * 100 // (i * 100)),
 qty := round(qty - bottle * i, 3),
 ][0]
 for i in sort["Capacity"]
 ]
 cost = (btl * sort["Cost"]).sum()
 return cost
qtys["Cost"] = qtys["Input Litres"].map(MyFun)
qtys
                    
                  

Solving the challenge of Calculate Cheapest Bottle Combination with R

R solution 1 for Calculate Cheapest Bottle Combination, proposed by Konrad Gryczan, PhD:
library(tidyverse)
library(readxl)
path = "Excel/628 Bottle Price Optimization.xlsx"
input1 = read_excel(path, range = "A1:C6") %>% janitor::clean_names()
input2 = read_excel(path, range = "A8:A12") 
test = read_excel(path, range = "A8:B12")
df = expand_grid(A = 0:10, B = 0:10, C = 0:10, D = 0:10, E = 0:10) %>%
 mutate(rn = row_number()) %>% 
 pivot_longer(-rn, names_to = "capacity", values_to = "value") %>%
 left_join(input1, by = c("capacity" = "bottle_type"), keep = T) %>%
 mutate(cost = value * cost_bottle,
 capacity = value * capacity_l) %>%
 filter(capacity != 0) %>%
 mutate(combo = paste0(value, "x", bottle_type)) %>%
 summarise(total_cost = sum(cost),
 total_capacity = sum(capacity),
 combo = paste0(combo, collapse = ", "), 
 .by = rn)
 
total = input2 %>%
 left_join(df, by = c("Input Litres" = "total_capacity")) %>%
 mutate(lower_cost = min(total_cost, na.rm = T), .by = `Input Litres`) %>%
 filter(total_cost == lower_cost)
all.equal(total$total_cost, test$`Answer Expected`, check.attributes = F)
# [1] TRUE
                    
                  

&&

Leave a Reply