Home » Extract and SuM

Extract and SuM

Extract the buying and selling prices, then calculate profit/loss. For example, item 2 was sold at 50 but bought at 6,7, giving a loss of $17 Dynamic array function allowed, but Extra marks for Legacy solutions  or PowerQuery Solution

📌 Challenge Details and Links
Challenge Number: 71
Challenge Difficulty: ⭐
📥Download Sample File
📥Link to the solutions on LinkedIn

Solving the challenge of Extract and SuM with Power Query

Power Query solution 1 for Extract and SuM, proposed by Kris Jaganah:
let
  A = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  B = Table.AddColumn(
    A, 
    "Profit (loss)", 
    each [
      a = List.Transform(
        {0, 2}, 
        (v) => Number.From(Text.Middle(Text.Select([Narration], {"0" .. "9"}), v, 2))
      ), 
      b = (a{1}? ?? 0) - a{0}
    ][b]
  )
in
  B
Power Query solution 2 for Extract and SuM, proposed by Brian Julius:
let
  Source = #"Problem (Sheet1)", 
  RScript = R.Execute(
    "library(stringr)#(lf)df <- dataset#(lf)df$NumsText <- sapply(str_extract_all(df$Narration, ""d+""), function(x) paste(x, collapse = "", ""))#(lf)print(df)", 
    [dataset = Source]
  ), 
  df = RScript{[Name = "df"]}[Value], 
  Split = Table.SplitColumn(df, "NumsText", Splitter.SplitTextByDelimiter(","), {"Buy", "Sell"}), 
  Coal = Table.TransformColumnTypes(
    Table.AddColumn(Split, "Coal", each [Sell] ?? 0), 
    {{"Coal", Int64.Type}, {"Buy", Int64.Type}}
  ), 
  AddPL = Table.AddColumn(Coal, "Profit (loss)", each [Coal] - [Buy]), 
  Clean = Table.RemoveColumns(AddPL, {"Buy", "Sell", "Coal"})
in
  Clean
Power Query solution 3 for Extract and SuM, proposed by Meganathan Elumalai:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Transform = Table.TransformColumns(
    Source, 
    {
      "Narration", 
      each [
        l = {"0" .. "9"}, 
        lst = List.Transform(
          Splitter.SplitTextByCharacterTransition((c) => not List.Contains(l, c), l)(_), 
          (f) => Number.From(Text.Select(f, l))
        ), 
        fin = try lst{2} - lst{1} otherwise 0 - lst{1}
      ][fin]
    }
  ), 
  Result = Table.RenameColumns(Transform, {{"Narration", "Profit (Loss)"}})
in
  Result
Power Query solution 4 for Extract and SuM, proposed by Peter Krkos:
PowerQuery solution:
= Table.AddColumn(Source, "Profit (loss)", each 
 [ a = List.Transform(List.Select(Text.SplitAny([Narration], " ,!."), (x)=> Value.FromText(x) is number), Number.From),
 b = (a{1}? ?? 0) - a{0}
 ][b], Int64.Type)[[Items], [#"Profit (loss)"]]
Power Query solution 5 for Extract and SuM, proposed by Alexandre Garcia:
let
  H = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  P = {"0" .. "9"}, 
  L = Table.ToList(
    H, 
    each {
      _{0}, 
      ((b) => b{1} - b{0})(
        List.Transform(
          Splitter.SplitTextByCharacterTransition(P, (x) => not List.Contains(P, x))(_{1}), 
          each Number.From(Text.Select(_, P)) ?? 0
        )
      )
    }
  ), 
  C = Table.FromRows(L, {"Items", "Profit (loss)"})
in
  C
Power Query solution 6 for Extract and SuM, proposed by Krzysztof Kominiak:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Result = Table.AddColumn(
    Source, 
    "Profit [loss]", 
    each [
      a = List.Select(Text.Split(Text.Select([Narration], {" ", "0" .. "9"}), " "), (x) => x <> ""), 
      b = try (- Number.From(a{0}) + Number.From(a{1})) otherwise - Number.From(a{0})
    ][b]
  )[[Items], [#"Profit [loss]"]]
in
  Result

Solving the challenge of Extract and SuM with Excel

Excel solution 1 for Extract and SuM, proposed by Rick Rothstein:
=MAP(
   C4:C7,
   LAMBDA(
       x,
       LET(
           t,
           TEXTSPLIT(
               x,
               TEXTSPLIT(
                   x,
                   SEQUENCE(
                       10,
                       ,
                       0),
                   ,
                   1),
               ,
               1),
           IF(
               COUNTA(
                   t)=1,
               -t,
               SUM(
                   t*{-1,
                   1})))))
Excel solution 2 for Extract and SuM, proposed by 🇰🇷 Taeyong Shin:
=MMULT(
   --REGEXREPLACE(
       C4:C7,
       "^.*?(bd+b)(?:.*((?1)))?.*",
       {"$1",
       "${2:-0}"}),
   {-1;1})
Excel solution 3 for Extract and SuM, proposed by Kris Jaganah:
=MAP(
   C4:C7,
   LAMBDA(
       x,
       MMULT(
           EXPAND(
               --REGEXEXTRACT(
                   x,
                   "[0-9]+",
                   1),
               ,
               2,
               0),
           {-1;1})))
Excel solution 4 for Extract and SuM, proposed by Hussein SATOUR:
=MAP(
   C4:C7,
   LAMBDA(
       x,
       SUM(
           LET(
               a,
               REGEXEXTRACT(
                   x,
                   "d+",
                   1),
               a*IF(
                   COUNTA(
                       a)=1,
                   -1,
                   {-1,
                   1})))))
Excel solution 5 for Extract and SuM, proposed by Oscar Mendez Roca Farell:
=MAP(
   C4:C7,
   LAMBDA(
       a,
       SUM(
           IFNA(
               REGEXEXTRACT(
                   a&" 0",
                   "d+",
                   1)*{-1,
               1},
               ))))
Excel solution 6 for Extract and SuM, proposed by Sunny Baggu:
=MAP(
   
    C4:C7,
   
    LAMBDA(
        a,
        
         SUM(
             
              TAKE(
                  
                   HSTACK(
                       
                        --TEXTSPLIT(
                            a,
                             TEXTSPLIT(
                                 a,
                                  ,
                                  SEQUENCE(
                                      10,
                                       ,
                                       0),
                                  1),
                             ,
                             1),
                       
                        0
                        ),
                  
                   ,
                  
                   2
                   ) * {-1,
              1}
              )
         )
   )
Excel solution 7 for Extract and SuM, proposed by Pieter de B.:
=GROUPBY(
   B4:B7,
   MAP(
       C4:C7,
       LAMBDA(
           y,
           LET(
               z,
               REGEXEXTRACT(
                   y,
                   "[0-9]+",
                   1),
               SUM(
                   z*TAKE(
                       {-1,
                       1},
                       ,
                       COUNTA(
                           z)))))),
   SUM,
   ,
   0)

Or after seeing Kris Jaganah I realize I missed out on Expand:
=GROUPBY(
   B4:B7,
   MAP(
       C4:C7,
       LAMBDA(
           y,
           SUM(
               EXPAND(
                   REGEXEXTRACT(
                       y,
                       "[0-9]+",
                       1),
                   ,
                   2,
                   0)*{-1,
               1}))),
   SUM,
   ,
   0)
Excel solution 8 for Extract and SuM, proposed by Hamidi Hamid:
=LET(
   x,
   DROP(
       IFERROR(
           TEXTSPLIT(
               CONCAT(
                   "/"&C4:C7&","&"!"&"."),
               {" ",
               ",",
               ".",
               "!"},
               "/")*1,
           ""),
       1),
   xu,
   BYROW(
       x,
       LAMBDA(
           a,
           XLOOKUP(
               TRUE,
               a<>"",
               a,
               0,
               0,
               1))),
   xd,
   BYROW(
       x,
       LAMBDA(
           a,
           XLOOKUP(
               TRUE,
               a<>"",
               a,
               0,
               0,
               -1))),
   HSTACK(
       B4:B7,
       IF(
           xu=xd,
           -xd,
           xd-xu)))
Excel solution 9 for Extract and SuM, proposed by Asheesh Pahwa:
=HSTACK(
   B4:B7,
   MAP(
       C4:C7,
       LAMBDA(
           x,
           LET(
               s,
               --TEXTSPLIT(
                   x,
                   TEXTSPLIT(
                       x,
                       SEQUENCE(
                           10,
                           ,
                           0),
                       ,
                       1),
                   ,
                   1),
               IF(
                   COUNTA(
                       s)=1,
                   -s,
                   SUM(
                       s*{-1,
                       1}))))))
Excel solution 10 for Extract and SuM, proposed by Meganathan Elumalai:
=MAP(
   C4:C7,
   LAMBDA(
       x,
       MMULT(
           --EXPAND(
               TEXTSPLIT(
                   x,
                   TEXTSPLIT(
                       x,
                       SEQUENCE(
                           ,
                           10,
                           0),
                       ,
                       1),
                   ,
                   1),
               ,
               2,
               0),
           {-1;1})))
Excel solution 11 for Extract and SuM, proposed by Eddy Wijaya:
=REDUCE(
   E3:F3,
   C4:C7,
   LAMBDA(
       a,
       v,
       VSTACK(
           a,
           LET(
               
               t,
               TOROW(
                   --TEXTSPLIT(
                       v,
                       {" ",
                       ",",
                       "!"}),
                   3),
               
               a,
               IF(
                   COLUMNS(
                       t)=1,
                   HSTACK(
                       t,
                       0),
                   t),
               
               pl,
               BYROW(
                   a,
                   LAMBDA(
                       r,
                       TAKE(
                           r,
                           ,
                           -1)-@r)),
               
               HSTACK(
                   "Item "&XMATCH(
                       v,
                       C4:C7,
                       0),
                   pl)))))
Excel solution 12 for Extract and SuM, proposed by Mey Tithveasna:
=LET(
   t,
   MAP(
       A2:A5,
       LAMBDA(
           a,
           TEXTJOIN(
               ",",
               ,
               REGEXEXTRACT(
                   a,
                   "d+",
                   1)))),
   res,
   IFNA(
       TEXTAFTER(
           t,
           ",")-
       TEXTBEFORE(
           t,
           ","),
       -t),
   res)
Excel solution 13 for Extract and SuM, proposed by Erdit Qendro:
=LET(
   ar,
   B4:C7,
   
   x,
   BYROW(
       DROP(
           ar,
           ,
           1),
       
       LAMBDA(
           a,
           TEXTJOIN(
               " | ",
               ,
               REGEXEXTRACT(
                   a,
                   "(d+)",
                   1)))),
   
   prls,
   IFERROR(
       TEXTAFTER(
           x,
           " | ")-TEXTBEFORE(
           x,
           " | "),
       -x),
   
   VSTACK(
       {"Items",
       "Profit (loss)"},
       
       HSTACK(
           TAKE(
           ar,
           ,
           1),
           prls)))
Excel solution 14 for Extract and SuM, proposed by Ernesto Vega Castillo:
=LET(
   i,
   B4:B7,
   a,
   IFNA(
       WRAPROWS(
           --REGEXEXTRACT(
               CONCAT(
                   C4:C7),
               "[0-9]+",
               1,
               1),
           2),
       0),
   HSTACK(
       i,
       DROP(
           TAKE(
               a,
               ,
               2)-TAKE(
               a,
               ,
               1),
           ,
           1)))

Solving the challenge of Extract and SuM with Python

Python solution 1 for Extract and SuM, proposed by Konrad Gryczan, PhD:
import pandas as pd
import re
path = "files/Challenge1225.xlsx"
input = pd.read_excel(path, usecols="B:C", skiprows=2, nrows=5)
test = pd.read_excel(path, usecols="E:F", skiprows=2, nrows=5).rename(columns=lambda col: re.sub(r'.1$', '', col))
input = input.assign(
 Narration=input['Narration'].str.split(r'[,.]')
).explode('Narration').dropna(subset=['Narration'])
input['action'] = input['Narration'].str.extract(r'(sell|sold|buy)', expand=False)
input = input.dropna(subset=['action'])
input['amount'] = input['Narration'].str.extract(r'(d+)').astype('int64')
input.loc[input['action'] == 'buy', 'amount'] *= -1
result = input.groupby('Items', sort=False)['amount'].sum().rename('Profit (loss)').reset_index()
print(result.equals(test)) # True

Solving the challenge of Extract and SuM with Python in Excel

Python in Excel solution 1 for Extract and SuM, proposed by Alejandro Campos:
import re
df = xl("B3:C7", headers=True)
def extract_prices(narration, item_name):
 if item_name == "Item 4": return 16, 0
 prices = re.findall(r'd+', narration)
 return (int(prices[0]), int(prices[1])) if len(prices) >= 2 else (0, 0)
df[['Buying Price', 'Selling Price']] = df.apply(lambda x: pd.Series(extract_prices(x['Narration'], x['Items'])), axis=1)
df['Profit/Loss'] = df['Selling Price'] - df['Buying Price']
df[['Items', 'Buying Price', 'Selling Price', 'Profit/Loss']]

Solving the challenge of Extract and SuM with R

R solution 1 for Extract and SuM, proposed by Konrad Gryczan, PhD:
library(tidyverse)
library(readxl)
path = "files/Challenge1225.xlsx"
input = read_excel(path, range = "B3:C7")
test  = read_excel(path, range = "E3:F7")
result = input %>%
 separate_rows(Narration, sep = "[,.]") %>%
 mutate(action = case_when(
 str_detect(Narration, "sell|sold") ~ "sell",
 str_detect(Narration, "buy") ~ "buy",
 TRUE ~ NA_character_
 ))  %>%
 na.omit() %>%
 mutate(amount = as.numeric(str_extract(Narration, "\d+")) * ifelse(action == "buy", -1, 1)) %>%
 summarise(`Profit (loss)` = sum(amount), .by = Items)
all.equal(result, test, check.attributes = FALSE)
#> [1] TRUE

Leave a Reply