Home » Rank by Best of 3 Subjects

Rank by Best of 3 Subjects

Generate the result table from problem table. Work out the total marks for best of 3 subjects. Rank students within the class on the basis of this best of 3 subjects marks.

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

Solving the challenge of Rank by Best of 3 Subjects with Power Query

Power Query solution 1 for Rank by Best of 3 Subjects, proposed by Bo Rydobon 🇹🇭:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Ans = Table.Combine(
    List.Transform(
      Table.ToRows(Source), 
      each Table.AddRankColumn(
        Table.AddColumn(
          Table.FromRows(
            List.Transform(List.Split(List.Skip(List.RemoveNulls(_)), 6), (l) => {_{0}} & l), 
            List.FirstN(Table.ColumnNames(Source), 7)
          ), 
          "Best of 3 Total", 
          each List.Sum(List.MaxN(List.Skip(Record.ToList(_), 2), 3))
        ), 
        "Rank", 
        {"Best of 3 Total", 1}
      )
    )
  )
in
  Ans
Power Query solution 2 for Rank by Best of 3 Subjects, proposed by Zoran Milokanović:
let
  Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content], 
  S = Table.FromRows(
    List.Accumulate(
      List.Sort(
        List.Combine(
          List.Transform(
            Table.ToRows(Source), 
            each 
              let
                r = List.RemoveNulls(_)
              in
                List.Transform(
                  List.Split(List.Skip(r), 6), 
                  (n) => {r{0}} & n & {List.Sum(List.FirstN(List.Sort(List.Skip(n), 1), 3))}
                )
          )
        ), 
        {each _{0}, {each _{7}, 1}, each _{1}}
      ), 
      {}, 
      (s, c) =>
        s
          & {
            c
              & {
                if List.Last(s, {0}){0} <> c{0} then
                  1
                else
                  List.Last(s){8} + Number.From(List.Last(s){7} <> c{7})
              }
          }
    ), 
    List.FirstN(Table.ColumnNames(Source), 7) & {"Best of 3 Total", "Rank"}
  )
in
  S
Power Query solution 3 for Rank by Best of 3 Subjects, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Group = Table.Group(
    Source, 
    {"Class"}, 
    {
      {
        "All", 
        each 
          let
            a = Table.RemoveColumns(_, "Class"), 
            b = List.Transform(Table.ToRows(a), each List.Split(_, 6)){0}, 
            c = Table.SelectRows(
              Table.FromRows(b, List.Skip(List.FirstN(Table.ColumnNames(Source), 7))), 
              each [Student] <> null
            ), 
            d = Table.AddColumn(
              c, 
              "Best of 3 Total", 
              each List.Sum(List.MaxN(List.Skip(Record.ToList(_)), 3))
            ), 
            e = Table.AddRankColumn(
              d, 
              "Rank", 
              {"Best of 3 Total", Order.Descending}, 
              [RankKind = RankKind.Dense]
            )
          in
            Table.SelectRows(e, each [Rank] < 4)
      }
    }
  ), 
  Sol = Table.ExpandTableColumn(Group, "All", Table.ColumnNames(Group[All]{0}))
in
  Sol
Power Query solution 4 for Rank by Best of 3 Subjects, proposed by Luan Rodrigues:
let
  Fonte = Tabela1, 
  un = Table.UnpivotOtherColumns(Fonte, {"Class"}, "Atributo", "Valor"), 
  add = Table.AddColumn(
    un, 
    "Student", 
    each if Text.StartsWith([Atributo], "Student") then [Valor] else null
  ), 
  pb = Table.FillDown(add, {"Student"}), 
  fil = Table.SelectRows(pb, each [Valor] is number), 
  gp = Table.Group(
    fil, 
    {"Class", "Student"}, 
    {
      {
        "Contagem", 
        each [
          tab = Table.TransformColumns(_, {{"Atributo", each Text.Start(_, 4), type text}}), 
          Un = Table.Pivot(tab, List.Distinct(tab[Atributo]), "Atributo", "Valor", List.Sum), 
          Best = Table.AddColumn(
            Un, 
            "Best of 3 Total", 
            each List.Sum(List.MaxN(List.RemoveFirstN(Record.FieldValues(_), 2), 3))
          )
        ][Best]
      }
    }
  ), 
  exp = Table.ExpandTableColumn(
    gp, 
    "Contagem", 
    List.RemoveFirstN(Table.ColumnNames(gp[Contagem]{0}), 2)
  ), 
  grp = Table.Group(
    exp, 
    {"Class"}, 
    {
      {
        "Contagem", 
        each Table.AddRankColumn(
          Table.Sort(_, {{"Best of 3 Total", Order.Descending}}), 
          "Rank", 
          {"Best of 3 Total", Order.Descending}
        )
      }
    }
  ), 
  res = Table.ExpandTableColumn(
    grp, 
    "Contagem", 
    List.RemoveFirstN(Table.ColumnNames(grp[Contagem]{0}), 1)
  )
in
  res
Power Query solution 5 for Rank by Best of 3 Subjects, proposed by Brian Julius:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  UnpivotOther = Table.UnpivotOtherColumns(Source, {"Class"}, "Attribute", "Value"), 
  AddStudent = Table.FillDown(
    Table.AddColumn(
      UnpivotOther, 
      "Student", 
      each if Value.Type([Value]) = Number.Type then null else [Value]
    ), 
    {"Student"}
  ), 
  Filter = Table.RemoveColumns(
    Table.SelectRows(AddStudent, each Text.StartsWith([Attribute], "Sub")), 
    "Attribute"
  ), 
  AddBestOf3 = Table.Group(
    Filter, 
    {"Class", "Student"}, 
    {"BestOf3", each List.Sum(List.FirstN(List.Sort([Value], Order.Descending), 3)), Int64.Type}
  ), 
  Group = Table.Group(
    AddBestOf3, 
    {"Class"}, 
    {{"All", each _, type table [Class = number, Student = text, BestOf3 = number]}}
  ), 
  AddRank = Table.RemoveColumns(
    Table.AddColumn(
      Group, 
      "RankScores", 
      each Table.AddRankColumn(
        [All], 
        "Rank", 
        {"BestOf3", Order.Descending}, 
        [RankKind = RankKind.Dense]
      )
    ), 
    "All"
  ), 
  Expand = Table.ExpandTableColumn(
    AddRank, 
    "RankScores", 
    {"Student", "BestOf3", "Rank"}, 
    {"Student", "BestOf3", "Rank"}
  )
in
  Expand
Power Query solution 6 for Rank by Best of 3 Subjects, proposed by Matthias Friedmann:
let
  Source = Excel.CurrentWorkbook(){[Name = "StudentSub"]}[Content], 
  Unpivoted = Table.UnpivotOtherColumns(Source, {"Class"}, "Attribute", "Value"), 
  Replaced = Table.ReplaceValue(
    Unpivoted, 
    each [Attribute], 
    each if Text.StartsWith([Attribute], "Student") then "Student" else Text.Start([Attribute], 4), 
    Replacer.ReplaceValue, 
    {"Attribute"}
  ), 
  Student = Table.AddColumn(
    Replaced, 
    "Student", 
    each if [Attribute] = "Student" then [Value] else null
  ), 
  FilledDown = Table.FillDown(Student, {"Student"}), 
  Filtered = Table.SelectRows(FilledDown, each ([Attribute] <> "Student")), 
  Pivoted = Table.Pivot(Filtered, List.Distinct(Filtered[Attribute]), "Attribute", "Value"), 
  Best3 = Table.AddColumn(
    Pivoted, 
    "Best of 3 Total", 
    each List.Sum(List.MaxN(List.RemoveFirstN(Record.ToList(_), 2), 3))
  ), 
  Grouped = Table.Group(
    Best3, 
    {"Class"}, 
    {{"All", each Table.AddRankColumn(_, "Rank", {"Best of 3 Total", Order.Descending})}}
  )[All], 
  Expand = Table.Combine(Grouped)
in
  Expand
Power Query solution 7 for Rank by Best of 3 Subjects, proposed by Kerwin Tan CPA:
let
  Source = Excel.CurrentWorkbook(){[Name = "problem"]}[Content], 
  #"Promoted Headers" = Table.PromoteHeaders(Source, [PromoteAllScalars = true]), 
  result = 
    let
      a = Table.ToRows(#"Promoted Headers"), 
      b = List.Transform(
        a, 
        each 
          let
            ba = List.RemoveNulls(_), 
            bb = List.Split(List.Skip(ba, 1), 6), 
            bc = List.Transform(
              bb, 
              each {List.First(ba)} & _ & {List.Sum(List.MaxN(List.Skip(_, 1), 3))}
            )
          in
            Table.FromRows(
              bc, 
              {"Class", "Student", "Sub1", "Sub2", "Sub3", "Sub4", "Sub5", "Best of 3 Total"}
            )
      ), 
      c = List.Transform(
        b, 
        each Table.AddRankColumn(
          _, 
          "Rank", 
          {"Best of 3 Total", Order.Descending}, 
          [RankKind = RankKind.Competition]
        )
      )
    in
      Table.Combine(c)
in
  result

Solving the challenge of Rank by Best of 3 Subjects with Excel

Excel solution 1 for Rank by Best of 3 Subjects, proposed by Bo Rydobon 🇹🇭:
=LET(a,B2:Y5,c,TOCOL(IFS(a>"",A2:A5),3),b,WRAPROWS(TOCOL(a,3),6),t,BYROW(b,LAMBDA(c,SUM(LARGE(c,{1,2,3})))),
VSTACK(HSTACK(A1:G1,{"Best of 3 Total","Rank"}),SORT(HSTACK(c,b,t,MAP(c,t,LAMBDA(d,s,XMATCH(s,UNIQUE(SORT(FILTER(t,c=d),,-1)))))),{1,9})))
Excel solution 2 for Rank by Best of 3 Subjects, proposed by محمد حلمي:
=REDUCE(HSTACK(UNIQUE(A1:Y1,1),"Best of 3 Total",
"Rank"),A2:A5,LAMBDA(a,d,LET(V,OFFSET(d,,1,,24),
x,WRAPROWS(FILTER(V,V>0),6),c,BYROW(x,LAMBDA(
q,SUM(TAKE(SORT(q,,-1,1),,4)))),p,SORT(c,,-1),VSTACK(a,
HSTACK(SORT(IFNA(HSTACK(d,x,c),d),8,-1),SCAN(0,
p<>DROP(VSTACK(0,p),-1),LAMBDA(a,d,a+d)))))))
Excel solution 3 for Rank by Best of 3 Subjects, proposed by Sunny Baggu:
=LET(
 _tbl, WRAPROWS(TOCOL(B2:Y5, 3), 6),
 class, MAP(TAKE(_tbl, , 1), LAMBDA(b, FILTER(A2:A5, BYROW(B2:Y5 = b, LAMBDA(a, OR(a)))))),
 uclass, UNIQUE(class),
 name, TAKE(_tbl, , 1),
 _stbl, SORTBY(_tbl, class, , name, ),
 _best3sum, MAKEARRAY(ROWS(_stbl), 1, LAMBDA(r, c, INDEX(SUM(DROP(SORT(INDEX(DROP(_stbl, , 1), r, ), , , 1), , 2)), c))),
 rank, TEXTSPLIT(
 ARRAYTOTEXT(MAP(uclass, LAMBDA(a, LET(_f, FILTER(_best3sum, class = a), ARRAYTOTEXT(XMATCH(_f, SORT(_f, , -1))))))),
 ,
 ", "
 ),
 HSTACK(class, _stbl, _best3sum, rank)
)
Excel solution 4 for Rank by Best of 3 Subjects, proposed by LEONARD OCHEA 🇷🇴:
=LET(t,A1:Y5,d,DROP(t,1,1),y,DROP(TAKE(t,,1),1),m,WRAPROWS(TOCOL(d,1),6),n,BYROW(DROP(m,,1),LAMBDA(a,SUM(TAKE(SORT(a,,-1,1),,3)))),c,MAP(TAKE(m,,1),LAMBDA(a,MAX(IF(a=d,y)))),o,SORTBY(HSTACK(c,m,n),c,1,n,-1),r,REDUCE("Rank",y,LAMBDA(a,b,VSTACK(a,LET(p,FILTER(TAKE(o,,-1),c=b),XLOOKUP(p,p,SEQUENCE(COUNT(p)),,-1))))),HSTACK(VSTACK(HSTACK(TAKE(t,1,7),"Best of 3 Total"),o),r))
Excel solution 5 for Rank by Best of 3 Subjects, proposed by Pieter de B.:
=LET(w,WRAPROWS(TOCOL(B2:Y5),6,1),f,FILTER(HSTACK(INDEX(A2:A5,INT(SEQUENCE(ROWS(w),,1,1/ROWS(A2:A5))),),w),ISTEXT(TAKE(w,,1))),h,HSTACK(INDEX(A2:A5,INT(SEQUENCE(ROWS(w),,1,1/ROWS(A2:A5))),),w),s,BYROW(TAKE(f,,-5),LAMBDA(b,SUM(TAKE(SORT(b,,,1),,-3)))),r,MMULT((TOROW(TAKE(f,,1))=TAKE(f,,1))*(TOROW(s)>s),SEQUENCE(ROWS(s),,,0))+1,VSTACK(HSTACK(A1:G1,"Total","Rank"),SORT(HSTACK(f,s,r),{1,9})))
Excel solution 6 for Rank by Best of 3 Subjects, proposed by Asheesh Pahwa:
=REDUCE(HSTACK(A1:G1, "Best of 3 Total","Rank"),SEQUENCE(4), LAMBDA(acc,itr,LET(a,INDEX(A2:Y5,itr,),
b,TRANSPOSE(a),
c,ISNUMBER(DROP(b,1)),
d,WRAPROWS(FILTER(DROP(b,1),c),5), 
e,TAKE(b,1)&"-"&FILTER(b,ISTEXT(b)),
f,BYROW(d,LAMBDA(x,SUM(LARGE(x,SEQUENCE(3))))), g,TEXTSPLIT(e,"-"),
h,TEXTAFTER(e,"-"), 1),
VSTACK(acc,HSTACK(g,SORTBY(h,f,-1),SORTBY(d,f,-1),SORT(f,,-1),XMATCH(SORT(f,,-1),SORT(f,,-1)))))))
Excel solution 7 for Rank by Best of 3 Subjects, proposed by Ziad A.:
={A1:G1,"Best of 3 Total","Rank";SORT(LET(v,REDUCE(TOCOL(,1),SEQUENCE(4),LAMBDA(a,c,VSTACK(a,QUERY(CHOOSECOLS(A2:5,1,SEQUENCE(6,1,6*(c-1)+2)),"where Col2<>''",)))),c,INDEX(v,,1),l,BYROW(v,LAMBDA(r,SUM(LARGE(r,{1,2,3})))),{v,l,MAP(c,l,LAMBDA(_c,_l,RANK(_l,FILTER(l,c=_c))))}),1,1,9,1)
Excel solution 8 for Rank by Best of 3 Subjects, proposed by Md Ismail Hosen:
=LET(Data, A2:Y5, fx_OneRow, LAMBDA(OneRow, LET(OneRow2, A5:Y5, WrappedData, WRAPROWS(DROP(OneRow, , 1), 6), RemoveBlanks, FILTER(WrappedData, CHOOSECOLS(WrappedData, 1) <> ""), BestThreeTotal, BYROW(RemoveBlanks, LAMBDA(row, SUM(TAKE(SORT(DROP(row, , 1), , , TRUE), , -3)))), MarkWithBestThree, SORTBY(HSTACK(RemoveBlanks, BestThreeTotal), BestThreeTotal, -1), Rank, XMATCH(CHOOSECOLS(MarkWithBestThree, -1), CHOOSECOLS(MarkWithBestThree, -1), 0), Result, HSTACK(SEQUENCE(ROWS(Rank), , INDEX(OneRow, 1, 1), 0), MarkWithBestThree, Rank), Result)), REDUCE(HSTACK(A1:G1, "Best Of 3 Total", "Rank"), SEQUENCE(ROWS(Data)), LAMBDA(a,v, VSTACK(a, fx_OneRow(CHOOSEROWS(Data, v))))))

&&&

Leave a Reply