Home » Maximize Buy-Sell Profit Days

Maximize Buy-Sell Profit Days

You will need to buy first and sell later. You can’t sell without buying. Also only one buy and one sell is permitted. You need to provide a formula to list Buy day and Sell day to maximize profit by buying first and selling later. In case of a tie, gap between Buy and Sell days should be minimum. For example – Value of 7 is for Day 4 and Day 6 both and sell is for Day 8 to maximize profit. But we will choose Day 6 and Day 8 to minimize the gap between Buy and Sell Day.

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

Solving the challenge of Maximize Buy-Sell Profit Days with Power Query

Power Query solution 1 for Maximize Buy-Sell Profit Days, proposed by Bo Rydobon 🇹🇭:
let
  z = Table.ToRows(Excel.CurrentWorkbook(){[Name = "Table1"]}[Content]), 
  Ans = Table.FromColumns(
    {
      {"Buy", "Sell"}, 
      List.Skip(
        List.Last(
          List.Sort(
            List.Transform(
              {1 .. List.Count(z) - 1}, 
              (s) =>
                List.Last(
                  List.Sort(
                    List.Transform({0 .. s - 1}, (b) => {z{b}{1} - z{s}{1}, z{b}{0}, z{s}{0}}), 
                    each _{0}
                  )
                )
            ), 
            each _{0}
          )
        )
      )
    }
  )
in
  Ans
Power Query solution 2 for Maximize Buy-Sell Profit Days, proposed by Zoran Milokanović:
let
  Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content], 
  S = 
    let
      l = Source[Price], 
      f = (s, p1, p2) =>
        let
          dp = l{p1} - l{p2}, 
          ds = l{s{0}} - l{s{1}}
        in
          if s = {} or dp > ds or (dp = ds and p2 - p1 < s{1} - s{0}) then {p1, p2} else s, 
      c = {"Buy", "Sell"}, 
      p = List.Accumulate(
        {0 .. List.Count(l) - 2}, 
        {}, 
        (ss, cc) =>
          let
            r = List.Accumulate({cc + 1 .. List.Count(l) - 1}, {}, (s, c) => f(s, cc, c))
          in
            f(ss, r{0}, r{1})
      )
    in
      Table.FromRows(
        List.Transform(List.Positions(p), each {c{_}, Source[Day]{p{_}}}), 
        {"Answer", "Expected"}
      )
in
  S
Power Query solution 3 for Maximize Buy-Sell Profit Days, proposed by Aditya Kumar Darak 🇮🇳:
let
  Source = Excel.CurrentWorkbook(){[Name = "data"]}[Content], 
  Count = Table.RowCount(Source) - 1, 
  Generate = List.TransformMany(
    {0 .. Count}, 
    (x) => {x + 1 .. Count}, 
    (x, y) => [
      B    = Source[Price]{x}, 
      S    = Source[Price]{y}, 
      D1   = B - S, 
      D2   = y - x + 1, 
      Buy  = Source[Day]{x}, 
      Sell = Source[Day]{y}
    ]
  ), 
  Max = List.Max(Generate, null, each [D1])[D1], 
  Return = List.Min(List.Select(Generate, each [D1] = Max), null, each [D2])[[Buy], [Sell]]
in
  Return
Power Query solution 4 for Maximize Buy-Sell Profit Days, proposed by Luke Jarych:
let
 sourceTable = Table1,
 numDays = Table.RowCount(sourceTable),
 buyDay = List.Min(sourceTable[Price])-1,
 sellDayOptions = List.Numbers(buyDay + 1, numDays - buyDay - 1), // Generate the records of  expected data
 pairsForBuyDay = List.Transform(
 sellDayOptions, 
 each [BuyDay = sourceTable{buyDay}[Day], SellDay = _ , SellDayName = sourceTable{SellDay}[Day] , Profit = sourceTable{SellDay}[Price] - sourceTable{buyDay}[Price], 
 PriceBuy = sourceTable{buyDay}[Price], PriceSell = sourceTable{SellDay}[Price]]
 ),
 transformedTable = Table.FromRecords(pairsForBuyDay),
 #"Filtered Rows" = Table.SelectRows(transformedTable, each ([Profit] = 14)),
 #"Removed Columns" = Table.RemoveColumns(#"Filtered Rows",{"SellDay"}),
 #"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"SellDayName", "SellDay"}})
in
 #"Renamed Columns"

In power Query to have the same result as yours in R ;-) 

Assumption is that i am buying in day with the lowest price. 


                    
                  
          

Solving the challenge of Maximize Buy-Sell Profit Days with Excel

Excel solution 1 for Maximize Buy-Sell Profit Days, proposed by Bo Rydobon 🇹🇭:
=LET(z,
    B2:B11,
    d,
    A2:A11,
    r,
    ROW(
        z
    ),
    t,
    TOROW(
        r
    ),
    c,
    LAMBDA(
        x,
        TOROW(
            IF(
                r
Excel solution 2 for Maximize Buy-Sell Profit Days, proposed by Bo Rydobon 🇹🇭:
=LET(z,
    B2:B11,
    d,
    A2:A11,
    r,
    ROW(
        z
    ),
    t,
    TOROW(
        r
    ),
    c,
    LAMBDA(
        x,
        TOROW(
            IF(
                r
Excel solution 3 for Maximize Buy-Sell Profit Days, proposed by John V.:
=LET(d,
    A2:A11,
    p,
    B2:B11,
    s,
    ROW(
        p
    ),
    t,
    TOROW(
        s
    ),
    v,
    IF(s
Excel solution 4 for Maximize Buy-Sell Profit Days, proposed by محمد حلمي:
=B2:B11-TOROW(
    B2:B11
)

=--(SEQUENCE(
    ,
    10
)>SEQUENCE(
    10
))


3 - 1*2 

=D2#*O2# 

=D15#*SEQUENCE(
    10
)


=LET(a,
    A2:A11,
    b,
    B2:B11,
    r,
    ROW(
        b
    ),
    i,
    r*(b-TOROW(
        b
    ))*(TOROW(
        r
    )>r),
    
HSTACK(
    {"Buy";"Sell"},
    TEXTSPLIT(
        @TOCOL(
            IFS(
                MAX(
                    i
                )=i,
                a&"-"&TOROW(
                    a
                )
            ),
            2
        ),
        ,
        "-"
    )
))
Excel solution 5 for Maximize Buy-Sell Profit Days, proposed by محمد حلمي:
=LET(
a,
    A2:A11,
    
b,
    B2:B11,
    
r,
    ROW(
        b
    ),
    
i,
    r*(b-TOROW(
        b
    ))*(TOROW(
        r
    )>r),
    
HSTACK(
    {"Buy";"Sell"},
    
    TEXTSPLIT(
        
        @TOCOL(
            IFS(
                MAX(
                    i
                )=i,
                a&"-"&TOROW(
                    a
                )
            ),
            2
        ),
        ,
        "-"
    )
))
Excel solution 6 for Maximize Buy-Sell Profit Days, proposed by Kris Jaganah:
=LET(a,
    A2:A11,
    b,
    B2:B11,
    c,
    --TEXTAFTER(
        a,
        "Day"
    ),
    d,
    TOROW(
        c
    ),
    e,
    IF(
        b0)*d),
    i,
    IF(
        h-g=0,
        "",
        h-g
    ),
    HSTACK(
        {"Buy";"Sell"},
        FILTER(
            VSTACK(
                "Day"&g,
                "Day"&h
            ),
            i=MIN(
                i
            )
        )
    ))
Excel solution 7 for Maximize Buy-Sell Profit Days, proposed by Timothée BLIOT:
=LET(
    A,
    MAKEARRAY(
        10,
        10,
        LAMBDA(
            x,
            y,
            IF(
                y>x,
                INDEX(
                    B2:B11,
                    x
                )-INDEX(
                    B2:B11,
                    y
                ),
                0
            )
        )
    ),
    "Day"&VSTACK(
        MAX(
            IF(
                A=MAX(
                    A
                ),
                SEQUENCE(
                    10
                )
            )
        ),
        MIN(
            IF(
                A=MAX(
                    A
                ),
                SEQUENCE(
                    ,
                    10
                )
            )
        )
    )
)
Excel solution 8 for Maximize Buy-Sell Profit Days, proposed by Oscar Mendez Roca Farell:
=LET(_d,
    B2:B11,
    _f,
    ROW(
        1:10
    ),
    _c,
    TOROW(
        _f
    ),
    _m,
    N(
        _f<_c
    )*(_d-TOROW(
        _d
    )),
    _e,
    TOCOL((_c+100*_f)/(_m=MAX(
        _m
    )),
    2),
    _r,
    MOD(
        _e,
        100
    ),
     _i,
    INT(
        _e/100
    ),
    _t,
    TAKE(
        SORTBY(
            HSTACK(
                _i,
                _r
            ),
            _r-_i
        ),
        1
    ),
    
HSTACK(
    {"Buy";"Sell"},
    "Day"&TOCOL(
        _t
    )
))
Excel solution 9 for Maximize Buy-Sell Profit Days, proposed by Oscar Mendez Roca Farell:
=LET(_d,
    B2:B11,
    _f,
    ROW(
        1:10
    ),
    _c,
    TOROW(
        _f
    ),
    _m,
    N(
        _f<_c
    )*(_d-TOROW(
        _d
    )),
    _e,
    TOCOL(_f&"00"&_c/(_m=MAX(
        _m
    )),
    2),
     _n,
    TEXTSPLIT(
        CONCAT(
            _e&"-"
        ),
        "00",
        "-",
        1
    ),
     _b,
    BYROW(
        _n,
        LAMBDA(
            r,
            SUM(
                r*{-1,
                1}
            )
        )
    ),
     HSTACK(
         {"Buy";"Sell"},
         "Day"&TOCOL(
             FILTER(
                 _n,
                 _b=MIN(
                     _b
                 )
             )
         )
     ))
Excel solution 10 for Maximize Buy-Sell Profit Days, proposed by Sunny Baggu:
=LET(
    
     _day,
     A2:A11,
    
     _price,
     B2:B11,
    
     _val1,
     TOROW(
         _price
     ) - _price,
    
     _val2,
     DROP(
         IFNA(
             REDUCE(
                 0,
                  SEQUENCE(
                      ROWS(
                          _day
                      )
                  ),
                  LAMBDA(
                      a,
                       v,
                       HSTACK(
                           a,
                            SEQUENCE(
                                v,
                                 ,
                                 0,
                                 0
                            )
                       )
                  )
             ),
              1
         ),
          ,
          1
     ),
    
     _val3,
     IF(
         _val2 > 0,
          _val1,
          0
     ),
    
     _max,
     MAX(
         _val3
     ),
    
     _col1,
     TOCOL(
         IF(
             _val3 = _max,
              TOROW(
                          _day
                      ),
              1 / x
         ),
          3
     ),
    
     _col2,
     TOCOL(
         IF(
             _val3 = _max,
              _day,
              1 / x
         ),
          3
     ),
    
     HSTACK(
         
          D2:D3,
         
          TOCOL(
              FILTER(
                  HSTACK(
                      _col1,
                       _col2
                  ),
                   MIN(
                       RIGHT(
                           _col2
                       ) - RIGHT(
                           _col1
                       )
                   ) = RIGHT(
                           _col2
                       ) - RIGHT(
                           _col1
                       )
              )
          )
          
     )
    
)
Excel solution 11 for Maximize Buy-Sell Profit Days, proposed by LEONARD OCHEA 🇷🇴:
=LET(d,
    A2:A11,
    p,
    B2:B11,
    r,
    TOROW(
        p
    ),
    s,
    SEQUENCE(
        ,
        ROWS(
        p
    )
    ),
    w,
    (s>TOCOL(
        s
    ))*(p-r)+ROW(
        p
    )*10^-9,
    m,
    MAX(
        w
    ),
    VSTACK(
        HSTACK(
            "Buy",
            @TOCOL(
                IFS(
                    w=m,
                    d
                ),
                2
            )
        ),
        HSTACK(
            "Sell",
            @TOCOL(
                IFS(
                    w=m,
                    TOROW(
                        d
                    )
                ),
                2
            )
        )
    ))
Excel solution 12 for Maximize Buy-Sell Profit Days, proposed by Pieter de Bruijn:
=LET(a,A2:A11,r,ROWS(a),m,DROP(REDUCE(0,B2:B11,LAMBDA(x,y,IFNA(HSTACK(x,TOCOL(y-y:B11)),""))),,1),x,XMATCH(MAX(m),TOCOL(m)),b,MOD(x,r),WRAPROWS(HSTACK("Buy",INDEX(a,b),"Sell",INDEX(a,b+ROUNDUP(x/r,)-1)),2))
Excel solution 13 for Maximize Buy-Sell Profit Days, proposed by samir tobeil:
=LET(a,A2:A11,b,B2:B11,s,MAP(b,LAMBDA(x,MAX(B2:x)-MIN(x:B11))),f,--(s=MAX(s))*b,
HSTACK({"Buy";"Sell"},VSTACK(XLOOKUP(MAX(f),f,a,,,-1),INDEX(a,XMATCH(MIN(FILTER(f,f>0)),f)))))

Solving the challenge of Maximize Buy-Sell Profit Days with Python in Excel

Python in Excel solution 1 for Maximize Buy-Sell Profit Days, proposed by Bo Rydobon 🇹🇭:
pr = xl("A2:B11").values
np.transpose([['Buy','Sell']]+[sorted(sorted([pr[j,1]-pr[i,1],pr[j,0],pr[i,0]] for j in range(i))[-1] for i in range(1,len(pr)))[-1][1:]])
Python in Excel solution 2 for Maximize Buy-Sell Profit Days, proposed by John V.:
Hi everyone!
p = xl("B2:B11")[0]
max_diff = 0
min_gap = len(p)
buy_day = 0
sell_day = 0
for x in range(len(p)):
 for y in range(x+1, len(p)):
 diff = p[x] - p[y]
 gap = y - x
 if diff > max_diff or (diff == max_diff and gap < min_gap):
 max_diff = diff
 min_gap = gap
 buy_day = x + 1
 sell_day = y + 1
[["Buy", "Day" + str(buy_day)], ["Sell", "Day" + str(sell_day)]]
Blessings!
                    
                  

Solving the challenge of Maximize Buy-Sell Profit Days with R

R solution 1 for Maximize Buy-Sell Profit Days, proposed& by Konrad Gryczan, PhD:
library(tidyverse)
library(readxl)
input = read_excel("Buy Sell.xlsx") %>% select(1,2)
achieve_max_profit = function(df) {
 
 df = df %>%
 mutate(day_number = parse_number(Day))
 
 grid = expand.grid(buy_day = df$day_number, sell_day = df$day_number) %>%
 filter(sell_day > buy_day)
 buy_prices = df %>%
 select(buy_day = day_number, buy_price = Price)
 sell_prices = df %>%
 select(sell_day = day_number, sell_price = Price)
 
 joined_data = grid %>%
 left_join(buy_prices, by = join_by(buy_day)) %>%
 left_join(sell_prices, by = join_by(sell_day)) %>%
 mutate(sell_delay = sell_day - buy_day,
 profit = sell_price - buy_price) %>%
 arrange(-profit, sell_delay) %>%
 slice(1)
 
 return(joined_data)
}
achieve_max_profit(input)
                    
                  

&&

Leave a Reply