Home » Consecutive Wins Within Span

Consecutive Wins Within Span

List the names who have won consecutively at least 3 times within a span of 180 days. Span of 180 days is last win date – first win date in a consecutive streak of wins. 2022-01-15 Y 2022-01-28 N 2022-02-12 Y 2022-03-18 Y 2022-05-12 Y Here all 3 consecutive wins are within 180 days 2022-05-12 – 2022-02-12 : 89 days (The winning streak of at least 3 consecutive wins start on 2022-02-12 not on 2022-01-15) 2022-01-15 Y 2022-01-28 Y 2022-02-12 N 2022-03-18 Y 2022-05-12 Y Here, 2022-02-12 N – Breaks at least 3 consecutive criterion If you may have more than one consecutive streaks of at least 3 consecutive wins, in this case, list any one of them. 2022-01-15 Y 2022-01-28 Y 2022-01-31 Y 2022-02-12 N 2022-03-18 Y 2022-05-12 Y 2022-06-08 Y 2022-06-28 Y Here, there are 2 streaks of consecutive wins Streak 1 2022-01-15 Y 2022-01-28 Y 2022-01-31 Y Streak 2 2022-03-18 Y 2022-05-12 Y 2022-06-08 Y 2022-06-28 Y List either of them. My preference would be Streak 1.

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

Solving the challenge of Consecutive Wins Within Span with Power Query

Power Query solution 1 for Consecutive Wins Within Span, proposed by Victor Wang:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Grouped = Table.Group(Source, {"Name"}, {{"all", each Table.Sort(_, each Date.From([Date]))}})[
    all
  ], 
  CreateLists = List.Transform(
    Grouped, 
    (a) =>
      List.Accumulate(
        Table.ToRecords(a), 
        {[d = null, r = null]}, 
        (state, current) =>
          if List.Last(state)[r] = null and current[Won] = "Y" then
            state & {[d = current[Date], r = {current}]}
          else if current[Won]
            = "Y" and Duration.Days(Date.From(current[Date]) - Date.From(List.Last(state)[d]))
            <= 180
          then
            List.RemoveLastN(state, 1)
              & {[d = List.Last(state)[d], r = List.Last(state)[r] & {current}]}
          else
            state & {[d = null, r = null]}
      )
  ), 
  Result = Table.FromRecords(
    List.Combine(
      Table.FromRecords(
        List.RemoveNulls(
          List.Transform(
            CreateLists, 
            each List.Select(_, (b) => b[d] <> null and List.Count(b[r]) >= 3){0}?
          )
        )
      )[r]
    )
  )[[Name], [Date]]
in
  Result
Power Query solution 2 for Consecutive Wins Within Span, proposed by Melissa de Korte:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table2"]}[Content], 
  GroupedLocal = Table.SelectRows(
    Table.Group(
      Source, 
      {"Name", "Won"}, 
      {
        {
          "Date", 
          each 
            if (Table.RowCount(_) >= 3 and [Won]{0} = "Y") then
              [
                d = List.Transform([Date], Date.From), 
                n = List.Union(
                  List.RemoveNulls(
                    List.Transform(
                      {0 .. List.Count(d) - 3}, 
                      each if Number.From(d{_ + 2} - d{_}) <= 180 then {_ .. _ + 2} else null
                    )
                  )
                ), 
                r = List.Transform(n, each d{_})
              ][r]
            else
              false
        }
      }, 
      GroupKind.Local
    ), 
    each ([Date] <> false)
  )[[Name], [Date]], 
  ExpandDate = Table.ExpandListColumn(GroupedLocal, "Date")
in
  ExpandDate
Power Query solution 3 for Consecutive Wins Within Span, proposed by Abdoul Karim N.:
let
  Source = Excel.CurrentWorkbook(){[Name = "Plays"]}[Content], 
  ChangedType = Table.TransformColumnTypes(
    Source, 
    {{"Name", type text}, {"Date", type date}, {"Won", type text}}
  ), 
  SortedRows = Table.Sort(ChangedType, {{"Name", Order.Ascending}, {"Date", Order.Ascending}}), 
  GroupRows = Table.Group(
    SortedRows, 
    {"Name", "Won"}, 
    {
      {
        "Count", 
        each _, 
        type table [Name = nullable text, Date = nullable date, Won = nullable text]
      }, 
      {"Wins-Loss", each Table.RowCount(_), Int64.Type}
    }
  ), 
  OnlyWins = Table.SelectRows(GroupRows, each ([Won] = "Y" and [#"Wins-Loss"] >= 3)), 
  Days = Table.AddColumn(
    OnlyWins, 
    "Days", 
    each Number.From(
      List.Max(Table.Column([Count], "Date")) - List.Min(Table.Column([Count], "Date"))
    )
  ), 
  FilterDays = Table.SelectRows(Days, each [Days] <= 180), 
  RemovedOtherColumns = Table.SelectColumns(FilterDays, {"Count"}), 
  FinalResult = Table.ExpandTableColumn(
    RemovedOtherColumns, 
    "Count", 
    {"Name", "Date"}, 
    {"Name", "Date"}
  )
in
  FinalResult
Power Query solution 4 for Consecutive Wins Within Span, proposed by Guido Hendrickx:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  #"Changed Type" = Table.TransformColumnTypes(
    Source, 
    {{"Name", type text}, {"Date", type date}, {"Won", type text}}
  ), 
  #"Grouped Rows" = Table.Group(
    #"Changed Type", 
    {"Name", "Won"}, 
    {
      {"Count", each Table.RowCount(_), Int64.Type}, 
      {"Sub", each _, type table [Name = nullable text, Date = nullable date, Won = nullable text]}
    }, 
    GroupKind.Local
  ), 
  #"Filtered Rows" = Table.SelectRows(#"Grouped Rows", each [Count] >= 3), 
  #"Added Custom" = Table.AddColumn(
    #"Filtered Rows", 
    "Has 3 Strikes", 
    each Text.Contains(List.Accumulate([Sub][Won], "", (r, v) => r & v), "YYY")
  ), 
  #"Added Custom1" = Table.AddColumn(
    #"Added Custom", 
    "Duration", 
    each Duration.Days(List.Max([Sub][Date]) - List.Min([Sub][Date]))
  ), 
  #"Filtered Rows1" = Table.SelectRows(#"Added Custom1", each [Duration] <= 180), 
  #"Removed Duplicates" = Table.Distinct(#"Filtered Rows1", {"Name"}), 
  #"Removed Other Columns" = Table.SelectColumns(#"Removed Duplicates", {"Name", "Sub"}), 
  #"Expanded Sub" = Table.ExpandTableColumn(#"Removed Other Columns", "Sub", {"Date"}, {"Date"})
in
  #"Expanded Sub"

Solving the challenge of Consecutive Wins Within Span with Excel

Excel solution 1 for Consecutive Wins Within Span, proposed by Bo Rydobon 🇹🇭:
=LET(z,
    SORT(
        A2:C17,
        {1,
        2}
    ),
    n,
    TAKE(
        z,
        ,
        1
    ),
    d,
    INDEX(
        z,
        ,
        2
    ),
    w,
    TAKE(
        z,
        ,
        -1
    ),
    y,
    (w="Y"),
    c,
    y*(d-XLOOKUP(
        n&"Y",
        n&w,
        d
    )<=180),
    
FILTER(
    TAKE(
        z,
        ,
        2
    ),
    y*ISNUMBER(
        FIND(
            111,
            MAP(
                n,
                c,
                LAMBDA(
                    a,
                    b,
                    CONCAT(
                        FILTER(
                            c,
                            a=n
                        )
                    )
                )
            )
        )
    )
))
Excel solution 2 for Consecutive Wins Within Span, proposed by Bo Rydobon 🇹🇭:
=LET(z,
    SORT(
        A2:C20,
        {1,
        2}
    ),
    n,
    TAKE(
        z,
        ,
        1
    ),
    d,
    INDEX(
        z,
        ,
        2
    ),
    w,
    TAKE(
        z,
        ,
        -1
    ),
    y,
    N(
        w="Y"
    ),
    s,
    FIND(
        111,
        MAP(
            n,
            y,
            LAMBDA(
                a,
                b,
                CONCAT(
                    FILTER(
                        y,
                        a=n
                    )
                )
            )
        )
    ),
    
FILTER(TAKE(
        z,
        ,
        2
    ),
    IFERROR((MAP(
        n,
        s,
        LAMBDA(
            a,
            c,
            LET(
                x,
                INDEX(
                    FILTER(
                        d,
                        n=a
                    ),
                    c
                ),
                x
            )
        )
    )<=d)*y,
    )))
Excel solution 3 for Consecutive Wins Within Span, proposed by محمد حلمي:
=REDUCE(A1:B1,
    C2:C17,
    LAMBDA(a,
    d,
    
IF(AND(
"Y"=OFFSET(
    d,
    ,
    ,
    3
),
    
OFFSET(
    d,
    ,
    -2
)=OFFSET(
    d,
    ,
    -2,
    3
),
    
(OFFSET(
    d,
    2,
    -1
)-OFFSET(
    d,
    ,
    -1
)<181)),
    
UNIQUE(
    VSTACK(
        a,
        OFFSET(
            d,
            ,
            -2,
            3,
            2
        )
    )
),
    a)))
Excel solution 4 for Consecutive Wins Within Span, proposed by محمد حلمي:
=LET(
    
    b,
    A2:C17,
    
    i,
    {0;1;2},
    
    k,
    SEQUENCE(
        ROWS(
            b
        )
    ),
    
    e,
    MAP(
        k,
        LAMBDA(
            d,
            LET(
                
                v,
                CHOOSEROWS(
                    b,
                    d+i
                ),
                
                r,
                INDEX(
                    v,
                    ,
                    2
                ),
                
                AND(
                    INDEX(
                        v,
                        1,
                        1
                    )=INDEX(
                        v,
                        ,
                        1
                    ),
                    
                    INDEX(
                        r,
                        3
                    )-INDEX(
                        r,
                        1
                    )<181,
                    INDEX(
                        v,
                        ,
                        3
                    )="Y"
                )
            )
        )
    ),
    
    VSTACK(
        A1:B1,
        FILTER(
            TAKE(
                b,
                ,
                2
            ),
            
            MAP(
                k,
                LAMBDA(
                    d,
                    OR(
                        IFERROR(
                            INDEX(
                                e,
                                d-i
                            ),
                            
                        )
                    )
                )
            )
        )
    )
)
Excel solution 5 for Consecutive Wins Within Span, proposed by محمد حلمي:
=LET(c,
    A2:A17,
    y,
    (C2:C17="y"),
    
FILTER(A2:B17,
    
MAP(c,
    LAMBDA(a,
    LET(a,
    FILTER(B2:B17,
    (c=a)*y)+0,
    
(ROWS(
    a
)>2)*(MAX(
    a
)-MIN(
    a
)<180))))*y))
Excel solution 6 for Consecutive Wins Within Span, proposed by 🇰🇷 Taeyong Shin:
=LET(name,
     M2:M17,
     Dt,
     --N2:N17,
     Won,
     O2:O17,
    
Uname,
     UNIQUE(
         name
     ),
    
Bool,
     MAP(Uname,
     LAMBDA(m,
    
 LET(wList,
     FILTER(
         Won,
          name=m
     ),
    
 dtList,
     FILTER(Dt,
     (name=m)*(Won="Y")),
    
 IF(
     ISNUMBER(
         SEARCH(
             "Y, Y, Y",
              ARRAYTOTEXT(
                  wList
              )
         )
     ),
     
      DAYS(
          SMALL(
              dtList,
               3
          )+1,
           MIN(
               dtList
           )
      )<=180 
 )
 )
 )),
    
Result,
     REDUCE("",
     FILTER(
         Uname,
          Bool
     ),
     LAMBDA(a,
    b,
    
 VSTACK(a,
     FILTER(HSTACK(
         name,
          Dt
     ),
     (name=b)*(Won="Y")) )
)),
    
SORT(
    DROP(
        Result,
         1
    ),
     {1,
    2}
)
)
Excel solution 7 for Consecutive Wins Within Span, proposed by 🇰🇷 Taeyong Shin:
=LET(name,
     A2:A17,
     Dt,
     --B2:B17,
     Won,
     C2:C17,
    
Uname,
     UNIQUE(
         name
     ),
    
Bool,
     MAP(Uname,
     LAMBDA(m,
    
 LET(List,
     FILTER(Dt,
     (name=m)*(Won="Y")),
    
 (ROWS(
     List
 )>=3)*(DAYS(
     MAX(
     List
 )+1,
      MIN(
     List
 )
 )<=180)
 )
 )),
    
List,
     ARRAYTOTEXT(
         FILTER(
             Uname,
              Bool
         )
     ),
    
SORT(FILTER(HSTACK(
    name,
     Dt
),
     ISNUMBER(
         SEARCH(
             name,
              List
         )
     )*(Won="Y") ),
     {1,
    2})
)
Excel solution 8 for Consecutive Wins Within Span, proposed by Bhavya Gupta:
=LET(N,
    B3:B18,
    D,
    C3:C18,
    W,
    D3:D18,
    Wins_Cons,
    3,
    Comb,
    HSTACK(
        N,
        D,
        W
    ),
    a,
    SCAN(
        0,
        VSTACK(
            FALSE,
            DROP(
                N,
                1
            )=DROP(
                N,
                -1
            )
        )*VSTACK(
            FALSE,
            DROP(
                W,
                1
            )=DROP(
                W,
                -1
            )
        ),
        LAMBDA(
            x,
            y,
            IF(
                y,
                x,
                x+1
            )
        )
    ),
    f,
    FILTER(
        a,
        W="Y"
    ),
    u,
    UNIQUE(
        f
    ),
    R,
    FILTER(
        u,
        DROP(
            FREQUENCY(
                f,
                u
            ),
            -1
        )>=Wins_Cons
    ),
    My,
    DROP(REDUCE(0,
    R,
    LAMBDA(o,
    p,
    VSTACK(o,
    LET(t,
    FILTER(
        Comb,
        a=p
    ),
    i,
    ROWS(
        t
    ),
    q,
    CHOOSECOLS(
        t,
        2
    ),
    k,
    EXPAND(
        DROP(
            q,
            Wins_Cons-1
        ),
        i
    )-q,
    s,
    SEQUENCE(
        i
    ),
    FILTER(t,
    REDUCE(0,
    s,
    LAMBDA(x,
    y,
    LET(h,
    INDEX(
        k,
        y
    ),
    x+IFNA(IF(h<181,
    (s>=y)*(s
Excel solution 9 for Consecutive Wins Within Span, proposed by Stefan Olsson:
=QUERY(
    {A2:C17},
    "Select Col1, Col2 where Col3='Y' and Col1 matches '"&JOIN(
        "|",
        QUERY(
            {QUERY(
                {A2:C17},
                "select Col1, max(Col2), min(Col2), count(Col3), datediff(max(Col2),min(Col2)) where Col3='Y' group by Col1",
                 0
            )},
            "select Col1 where Col4>2 and Col5<=180",
            0
        )
    )&"' order by Col1, Col2 label Col1 'Name', Col2 'Date'"
)

Leave a Reply