Home » Sequential Counter For IDs

Sequential Counter For IDs

This challenge is contributed by Duy Tùng The task is to assign sequential numbers to the Result column based on the Number column. Each ID has corresponding numbers. If the numbers for an ID are not consecutive, they should be marked as 1. However, if the numbers are consecutive, they should be marked according to their count. For example, ID 1000008 has numbers 5, 7, 15, 16; since 5 and 7 are not consecutive, they would each be marked as 1. But since 15 and 16 are consecutive, they would be marked as 2, which is the correct result.

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

Solving the challenge of Sequential Counter For IDs with Power Query

_x000D_
Power Query solution 1 for Sequential Counter For IDs, proposed by Kris Jaganah:
let
  A = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  B = Table.AddIndexColumn(A, "Ix"), 
  C = Table.AddColumn(B, "Calc", each [ID] + ([Ix] / 100) - ([Number] / 100)), 
  D = Table.AddColumn(
    C, 
    "Answer Expected", 
    each List.Count(List.Select(C[Calc], (x) => x = [Calc]))
  )[[Answer Expected]]
in
  D
_x000D_ _x000D_
Power Query solution 2 for Sequential Counter For IDs, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Grp = Table.Combine(
    Table.Group(
      Source, 
      {"ID"}, 
      {
        {
          "A", 
          each 
            let
              a = _, 
              b = Table.AddIndexColumn(a, "Idx", 0), 
              c = Table.Group(
                b, 
                "Idx", 
                {{"B", each [[ID]]}, {"Answer", each List.Count([Number])}}, 
                0, 
                (x, y) =>
                  let
                    d = b[Number]{y} - b[Number]{y - 1}, 
                    e = if d <> 1 then 1 else 0
                  in
                    e
              )[[B], [Answer]]
            in
              c
        }
      }
    )[A]
  ), 
  Sol = Table.ExpandTableColumn(Grp, "B", Table.ColumnNames(Grp[B]{0}))[[Answer]]
in
  Sol
_x000D_ _x000D_
Power Query solution 3 for Sequential Counter For IDs, proposed by Seokho MOON:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Group = Table.Group(
    Table.AddIndexColumn(Source, "Idx"), 
    {"ID", "Number", "Idx"}, 
    {"Answer Expected", each List.Repeat({Table.RowCount(_)}, Table.RowCount(_))}, 
    0, 
    (x, y) => Number.From(x[ID] <> y[ID] or x[Number] - x[Idx] <> y[Number] - y[Idx])
  )[[Answer Expected]], 
  Res = Table.ExpandListColumn(Group, "Answer Expected")
in
  Res
_x000D_ _x000D_
Power Query solution 4 for Sequential Counter For IDs, proposed by Meganathan Elumalai:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  AddCol = Table.ReplaceValue(
    Table.AddIndexColumn(Source, "Result"), 
    each [Number], 
    each [Result], 
    (x, y, z) => y - z, 
    {"Result"}
  ), 
  Result = Table.Combine(
    Table.Group(
      AddCol, 
      {"ID", "Result"}, 
      {
        "New", 
        each Table.ReplaceValue(
          _, 
          (x) => x[Result], 
          (y) => Table.RowCount(_), 
          Replacer.ReplaceValue, 
          {"Result"}
        )
      }, 
      0
    )[New]
  )[[Result]]
in
  Result
_x000D_ _x000D_
Power Query solution 5 for Sequential Counter For IDs, proposed by Antriksh Sharma:
let
  Source = Table, 
  Transform = List.TransformMany(
    List.Distinct(Source[ID]), 
    (x) => {
      let
        Data = Table.SelectRows(Source, each [ID] = x), 
        Result = Table.Group(
          Data, 
          "Number", 
          {
            "T", 
            each 
              let
                a = [Number], 
                b = List.Count(a), 
                c = List.Repeat({b}, b), 
                d = Table.FromColumns(Table.ToColumns(_) & {c}, {"ID", "Number", "Answer"})
              in
                d
          }, 
          GroupKind.Local, 
          (x, y) =>
            let
              a = {null} & Data[Number], 
              b = List.PositionOf(a, y), 
              c = (a{b} - a{b - 1}) <> 1, 
              d = Byte.From(c)
            in
              d
        )[T]
      in
        Result
    }, 
    (x, y) => Table.Combine(y)
  ), 
  Result = Table.Combine(Transform)
in
  Result
_x000D_ _x000D_
Power Query solution 6 for Sequential Counter For IDs, proposed by Peter Krkos:
PowerQuery solution:
= Table.Combine(Table.Group(Table.AddIndexColumn(Source, "i"), {"ID", "Number", "i"}, {{"T", each
 Table.AddColumn(Table.RemoveColumns(_, "i"), "Answer", (x)=> Table.RowCount(_), Int64.Type)}},
 0, (x,y)=> Byte.From( y[ID] <> x[ID] or Number.Abs(y[Number]-x[Number]) <> y[i]-x[i]))[T])
                    
                  
_x000D_ _x000D_
Power Query solution 7 for Sequential Counter For IDs, proposed by Aleksandar Kovacevic:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Lst = List.Transform(
    {0 .. List.Count(Source[ID]) - 1}, 
    each Source[ID]{_} * 100 - Source[Number]{_} + _
  ), 
  Res = Table.AddColumn(
    Table.FromColumns({Lst}, {"C"}), 
    "Answer Expected", 
    each List.Count(List.Select(Lst, (x) => x = [C]))
  )[[Answer Expected]]
in
  Res
_x000D_

Solving the challenge of Sequential Counter For IDs with Excel

_x000D_
Excel solution 1 for Sequential Counter For IDs, proposed by Bo Rydobon 🇹🇭:
=LET(
    n,
    A2:A29*100+B2:B29-ROW(
        B2:B29
    ),
    MAP(
        n,
        LAMBDA(
            x,
            SUM(
                N(
                    x=n
                )
            )
        )
    )
)
_x000D_ _x000D_
Excel solution 2 for Sequential Counter For IDs, proposed by John V.:
=LET(n,B2:B29,i,A2:A29+n%-ROW(n)%,MAP(i,LAMBDA(x,SUM(N(x=i)))))
_x000D_ _x000D_
Excel solution 3 for Sequential Counter For IDs, proposed by Kris Jaganah:
=LET(b,B2:B29,c,SEQUENCE(ROWS(b)),d,A2:A29+c/100-(b/100),MAP(d,LAMBDA(x,SUM(N(x=d)))))
_x000D_ _x000D_
Excel solution 4 for Sequential Counter For IDs, proposed by Kris Jaganah:
=REDUCE(
    "Answer Expected",
    UNIQUE(
        A2:A29
    ),
    LAMBDA(
        m,
        n,
        VSTACK(
            m,
            LET(
                a,
                FILTER(
                    B2:B29,
                    A2:A29=n
                ),
                b,
                SEQUENCE(
                    ROWS(
                        a
                    )
                ),
                c,
                a-XMATCH(
                    a+b,
                    a+b
                ),
                MAP(
                    c,
                    LAMBDA(
                        v,
                        SUM(
                            N(
                                v=c
                            )
                        )
                    )
                )
            )
        )
    )
)
_x000D_ _x000D_
Excel solution 5 for Sequential Counter For IDs, proposed by Timothée BLIOT:
=LET(
    A,
    A2:A29+B2:B29/100-ROW(
        1:28
    )/100,
    MAP(
        A,
        LAMBDA(
            x,
            SUM(
                N(
                    x=A
                )
            )
        )
    )
)
_x000D_ _x000D_
Excel solution 6 for Sequential Counter For IDs, proposed by Oscar Mendez Roca Farell:
=LET(d,B2:B29,n,A2:A29%+d-ROW(d),MAP(n,LAMBDA(a,SUM(N(n=a)))))
_x000D_ _x000D_
Excel solution 7 for Sequential Counter For IDs, proposed by Duy Tùng:
=LET(b,B2:B29,a,A2:A29&b-ROW(b),BYROW(N(a=TOROW(a)),SUM))
_x000D_ _x000D_
Excel solution 8 for Sequential Counter For IDs, proposed by Md. Zohurul Islam:
=LET(u,A2:A29,v,B2:B29,n,v-SEQUENCE(ROWS(u)),w,MAP(u,n,LAMBDA(x,y,SUM(ABS(u=x)*ABS(n=y)))),w)
_x000D_ _x000D_
Excel solution 9 for Sequential Counter For IDs, proposed by Hamidi Hamid:
=LET(
    x,
    SCAN(
        0,
        A1:A28<>A2:A29,
        SUM
    ),
    y,
    SCAN(
        0,
        B1:B28<>B2:B29-1,
        SUM
    ),
    w,
    x+y,
    v,
    MAP(
        w,
        LAMBDA(
            a,
            SUM(
                N(
                    w=a
                )
            )
        )
    ),
    v
)
_x000D_ _x000D_
Excel solution 10 for Sequential Counter For IDs, proposed by Asheesh Pahwa:
=REDUCE(
    D1,
    UNIQUE(
        A2:A29
    ),
    LAMBDA(
        x,
        y,
        VSTACK(
            x,
            LET(
                f,
                FILTER(
                    B2:B29,
                    A2:A29=y
                ),
                s,
                SEQUENCE(
                    ROWS(
                        f
                    )
                ),
                d,
                f-s,
                MAP(
                    d,
                    LAMBDA(
                        z,
                        SUM(
                            N(
                                d=z
                            )
                        )
                    )
                )
            )
        )
    )
)
_x000D_ _x000D_
Excel solution 11 for Sequential Counter For IDs, proposed by Dhaval Patel:
=SUMPRODUCT(($A$2:$A$29=A2)*((B$2:B$29-ROW(
    B$2:B$29
))=(B2-ROW())))
_x000D_ _x000D_
Excel solution 12 for Sequential Counter For IDs, proposed by Fredson Alves Pinho:
=LET(a,
    A2:A29,
    b,
    B2:B29-SEQUENCE(
        28
    ),
    MAP(a,
    b,
    LAMBDA(x,
    y,
    SUMPRODUCT(--(a=x),
    --(b=y)))))
_x000D_

Solving the challenge of Sequential Counter For IDs with Python

_x000D_
Python solution 1 for Sequential Counter For IDs, proposed by Konrad Gryczan, PhD:
import pandas as pd
path = "689 Consecutive Numbers Marking.xlsx"
input = pd.read_excel(path, usecols="A:B", nrows=29)
test = pd.read_excel(path, usecols="D", nrows=29)
input['rn'] = range(1, len(input) + 1)
input['group_id'] = (
 (input['ID'] != input['ID'].shift(1)) |
 ((input['Number'] - input['rn']) != (input['Number'] - input['rn']).shift(1))
).cumsum()
input['answer_expected'] = input.groupby('group_id')['group_id'].transform('size')
result = input[['answer_expected']]
print(result['answer_expected'].equals(test['Answer Expected']))
                    
                  
_x000D_

Solving the challenge of Sequential Counter For IDs with Python in Excel

_x000D_
Python in Excel solution 1 for Sequential Counter For IDs, proposed by Alejandro Campos:
df = xl("A1:B29", headers=True); df['orig_index'] = df.index
def f(g):
 g = g.sort_values('Number'); n = g['Number'].tolist(); r = [1]*len(n); i = 0
 while i < len(n):
 j = i
 while j+1 < len(n) and n[j+1] == n[j]+1: j += 1
 for k in range(i, j+1): r[k] = j - i + 1
 i = j + 1
 g['Result'] = r; return g
df = df.groupby('ID', group_keys=False).apply(f).sort_values('orig_index').drop(columns='orig_index').reset_index(drop=True)
                    
                  
_x000D_

Solving the challenge of Sequential Counter For IDs with R

_x000D_
R solution 1 for Sequential Counter For IDs, proposed by Konrad Gryczan, PhD:
library(tidyverse)
library(readxl)
path = "Excel/689 Consecutive Numbers Marking.xlsx"
input = read_excel(path, range = "A1:B29")
test  = read_excel(path, range = "D1:D29")
result = input %>%
 mutate(rn = row_number()) %>%
 group_by(
 group_id = cumsum(ID != lag(ID, default = first(ID)) | 
 (Number - rn) != lag(Number - rn, default = first(Number - rn)))
 ) %>%
 mutate(answer_expected = n()) %>%
 ungroup() %>%
 select(answer_expected)
all.equal(result$answer_expected, test$`Answer Expected`)
# TRUE
                    
                  
_x000D_ &&&

Leave a Reply