Home » Mark Overlapping Time Ranges

Mark Overlapping Time Ranges

If tasks’ From Time and To Time overlap with each other, mark them as Y. Ex. A’s From and To Times are 01:30 AM to 04:00 AM and B’s From and To Times are 02:00 AM to 05:30PM. There is overlap of times (02:00 AM to 04:00 AM) between A and B. Similarly, D’s To Time is 06:30 PM which overlaps with E’s Start Time of 06:30 PM. A task can not overlap with itself.

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

Solving the challenge of Mark Overlapping Time Ranges with Power Query

Power Query solution 1 for Mark Overlapping Time Ranges, proposed by John V.:
let
 S = Excel.CurrentWorkbook(){0}[Content],
 C = S[Task ID], A = Table.ToRows(S),
 L = List.TransformMany(A, each A, (x, y) => if y{2} < x{1} or y{1} > x{2} or x{0} = y{0} then null else "Y")
in
 Table.FromColumns({C} & List.Split(L, 7), {" "} & C)
Blessings!
                    
                  
          
Power Query solution 2 for Mark Overlapping Time Ranges, proposed by Zoran Milokanović:
let
  Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content], 
  R = Table.ToRows(Source), 
  S = Table.FromRows(
    List.TransformMany(
      R, 
      each {R}, 
      (i, _) => {i{0}}
        & List.Transform(
          _, 
          each {null, "Y"}{Number.From(List.AllTrue({_{0} <> i{0}, i{2} >= _{1}, _{2} >= i{1}}))}
        )
    ), 
    {" "} & Source[Task ID]
  )
in
  S
Power Query solution 3 for Mark Overlapping Time Ranges, proposed by Aditya Kumar Darak 🇮🇳:
let
  Source = Excel.CurrentWorkbook(){[Name = "data"]}[Content], 
  List = Table.AddColumn(
    Source, 
    "L", 
    each Table.SelectRows(
      Source, 
      (f) => (f[To Time] >= [From Time] and f[From Time] <= [To Time]) and f[Task ID] <> [Task ID]
    )[Task ID]
  ), 
  Expand = Table.ExpandListColumn(List, "L"), 
  Remove = Table.RemoveColumns(Expand, {"To Time"}), 
  Return = Table.Pivot(
    Remove, 
    List.Sort(List.Distinct(Remove[L])), 
    "L", 
    "From Time", 
    each if List.Count(_) > 0 then "Y" else null
  )
in
  Return
Power Query solution 4 for Mark Overlapping Time Ranges, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Tabla = List.Accumulate(
    Source[Task ID], 
    Source, 
    (s, c) =>
      Table.AddColumn(
        s, 
        c, 
        (x) =>
          let
            a = 
              if x[Task ID] = c then
                null
              else
                let
                  b = Table.SelectRows(Source, each [Task ID] = c), 
                  d = 
                    if b[To Time]{0} < x[From Time] or b[From Time]{0} > x[To Time] then
                      null
                    else
                      "Y"
                in
                  d
          in
            a
      )
  ), 
  Sol = Table.RemoveColumns(Tabla, {"From Time", "To Time"})
in
  Sol
Power Query solution 5 for Mark Overlapping Time Ranges, proposed by Ramiro Ayala Chávez:
let
  S = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  a = Table.TransformColumns(
    S, 
    {
      {
        "From Time", 
        each if Text.Length(Text.BeforeDelimiter(_, ":")) = 1 then Text.Insert(_, 0, "0") else _
      }, 
      {
        "To Time", 
        each if Text.Length(Text.BeforeDelimiter(_, ":")) = 1 then Text.Insert(_, 0, "0") else _
      }
    }
  ), 
  b = Table.TransformColumns(
    a, 
    {
      {"From Time", each Text.RemoveRange(Text.Remove(_, "."), 7, 1)}, 
      {"To Time", each Text.RemoveRange(Text.Remove(_, "."), 7, 1)}
    }
  ), 
  c = Table.TransformColumnTypes(b, {{"From Time", type time}, {"To Time", type time}}), 
  d = List.TransformMany(Table.ToRows(c), (x) => Table.ToRows(c), (x, y) => {x, y}), 
  e = List.Select(List.Transform(d, each List.Distinct(_)), each List.Count(_) = 2), 
  f = List.Transform(
    List.Transform(e, each List.Combine(_)), 
    each 
      if _{4}
        >= _{1} and _{4}
        <= _{2} or _{5}
        >= _{1} and _{5}
        <= _{2} or _{1}
        >= _{4} and _{1}
        <= _{5} or _{2}
        >= _{4} and _{2}
        <= _{5}
      then
        List.InsertRange(_, 0, {_{0} & _{3} & "Y"})
      else
        List.InsertRange(_, 0, {_{0} & _{3} & "N"})
  ), 
  g = Table.SplitColumn(
    Table.FromColumns({List.Transform(f, each _{0})}), 
    "Column1", 
    Splitter.SplitTextByRepeatedLengths(1), 
    {"C1", "C2", "C3"}
  ), 
  Sol = Table.ReorderColumns(
    Table.Pivot(
      Table.ReplaceValue(g, "N", null, Replacer.ReplaceValue, {"C3"}), 
      List.Distinct(g[C2]), 
      "C2", 
      "C3"
    ), 
    c[Task ID]
  )
in
  Sol
Power Query solution 6 for Mark Overlapping Time Ranges, proposed by Rafael González B.:
let
 Source = Table.TransformColumnTypes(
 Excel.CurrentWorkbook(){0}[Content], 
 {{"From Time", type datetime}, {"To Time", type datetime}}),
 TAC = Table.AddColumn,
 Laps = TAC(Source, "TimeRanges", each 
 let
 a = Duration.TotalHours([To Time] - [From Time]) * 4 + 1,
 b = List.Times([From Time], a, hashtag#duration(0,0,15,0)),
 c = List.RemoveLastN(List.RemoveFirstN(b))
 in 
 c)[[Task ID],[TimeRanges]],
 AddBase = TAC(Laps, "Base", each 1),
 Comb = Table.NestedJoin(AddBase, {"Base"}, AddBase, {"Base"}, "AddBase", 1),
 Exp = Table.ExpandTableColumn(Comb, "AddBase", 
 {"Task ID", "TimeRanges"}, {"Task ID.1", "TimeRanges.1"}),


                    
                  
          
Power Query solution 7 for Mark Overlapping Time Ranges, proposed by Venkata Rajesh:
let
  Source = Data, 
  Record = Table.AddColumn(
    Source, 
    "Record", 
    each [
      x = Table.SelectRows(
        Source, 
        (r) => [Task ID] <> r[Task ID] and [From Time] <= r[To Time] and [To Time] >= r[From Time]
      )[Task ID], 
      y = List.Repeat({"Y"}, List.Count(x)), 
      z = Record.FromList(y, x)
    ][z]
  )[[Task ID], [Record]], 
  Expand = Table.ExpandRecordColumn(Record, "Record", Source[Task ID])
in
  Expand

Solving the challenge of Mark Overlapping Time Ranges with Excel

Excel solution 1 for Mark Overlapping Time Ranges, proposed by Bo Rydobon 🇹🇭:
=LET(a,
    A2:A8,
    b,
    B2:B8,
    c,
    C2:C8,
    
HSTACK(VSTACK(
    "",
    a
),
    VSTACK(TOROW(
        a
    ),
    TRIM(MID(MAP(a,
    b,
    c,
    LAMBDA(i,
    f,
    t,
    CONCAT(IF((a<>i)*(t>=b)*(f<=c),
    "Y",
    " ")))),
    SEQUENCE(
        ,
        ROWS(
        a
    )
    ),
    1)))))
Excel solution 2 for Mark Overlapping Time Ranges, proposed by John V.:
=LET(i,
    A2:A8,
    b,
    B2:B8,
    c,
    C2:C8,
    r,
    TOROW,
    h,
    HSTACK,
    VSTACK(h(
        "",
        r(
            i
        )
    ),
    h(i,
    IF((cr(
        c
    ))+(i=r(
            i
        )),
    "",
    "Y"))))
Excel solution 3 for Mark Overlapping Time Ranges, proposed by محمد حلمي:
=LET(a,
    A2:A8,
    b,
    B2:B8,
    c,
    C2:C8,
    VSTACK(HSTACK(
        "",
        
        TOROW(
            a
        )
    ),
    HSTACK(a,
    IF(MUNIT(
        ROWS(
            b
        )
    ),
    "",
    
REPT("Y",
    (b<=TOROW(
        c
    ))*(c>=TOROW(
            b
        )))))))
Excel solution 4 for Mark Overlapping Time Ranges, proposed by 🇰🇷 Taeyong Shin:
=LET(i,
    A2:A8,
    f,
    B2:B8,
    t,
    C2:C8,
    a,
    TOCOL(IFS((f<=TOROW(
        t
    ))*(t>=TOROW(
        f
    ))*NOT(
        MUNIT(
            ROWS(
                i
            )
        )
    ),
    i&TOROW(
                i
            ))&"Y",
    2),
    PIVOTBY(
        LEFT(
            a
        ),
        MID(
            a,
            2,
            1
        ),
        RIGHT(
            a
        ),
        SINGLE,
        ,
        0,
        ,
        0
    ))
BY GROUPBY
=LET(i,
    A2:A8,
    f,
    B2:B8,
    t,
    C2:C8,
    VSTACK(HSTACK(
        "",
        TOROW(
                i
            )
    ),
    GROUPBY(i,
    REPT("Y",
    (f<=TOROW(
        t
    ))*(t>=TOROW(
        f
    ))*NOT(
        MUNIT(
            ROWS(
                i
            )
        )
    )),
    SINGLE,
    ,
    0)))
Excel solution 5 for Mark Overlapping Time Ranges, proposed by Kris Jaganah:
=LET(a,
    A2:A8,
    b,
    B2:B8*96,
    c,
    C2:C8*96,
    d,
    MAP(b,
    c,
    LAMBDA(y,
    z,
    ARRAYTOTEXT(FILTER(a,
    (by),
    0)))),
    e,
    TOROW(
        a
    ),
    f,
    IFERROR(
        IF(
            FIND(
                e,
                d
            ),
            "Y"
        ),
        ""
    ),
    VSTACK(
        HSTACK(
            "",
            e
        ),
        HSTACK(
            a,
            f&TRANSPOSE(
                f
            )
        )
    ))
Excel solution 6 for Mark Overlapping Time Ranges, proposed by Julian Poeltl:
=LET(
    T,
    A2:C8,
    P,
    TAKE(
        T,
        ,
        1
    ),
    TP,
    TRANSPOSE(
        P
    ),
    F,
    CHOOSECOLS(
        T,
        2
    ),
    To,
    TAKE(
        T,
        ,
        -1
    ),
    R,
    IF(
        MAP(
            XLOOKUP(
                P,
                P,
                To
            )>=XLOOKUP(
                TP,
                P,
                F
            ),
            XLOOKUP(
                P,
                P,
                F
            )<=XLOOKUP(
                TP,
                P,
                To
            ),
            TP<>P,
            LAMBDA(
                A,
                B,
                C,
                AND(
                    A,
                    B,
                    C
                )
            )
        ),
        "Y",
        ""
    ),
    VSTACK(
        HSTACK(
            "",
            TP
        ),
        HSTACK(
            P,
            R
        )
    )
)
Excel solution 7 for Mark Overlapping Time Ranges, proposed by Timothée BLIOT:
=LET(V,
    VSTACK,
    HSTACK(V(
        "",
        A2:A8
    ),
    V(TRANSPOSE(
        A2:A8
    ),
    IF(DROP(
        REDUCE(
            "",
            ROW(
                1:7
            ),
            LAMBDA(
                a,
                r,
                LET(
                    I,
                    INDEX,
                    B,
                    B2:B8,
                    C,
                    C2:C8,
                    D,
                    I(
                        B,
                        r,
                        1
                    ),
                    E,
                    I(
                        C,
                        r,
                        1
                    ),
                    V(
                        a,
                        --TOROW(
                            MAP(
                                B,
                                C,
                                LAMBDA(
                                    x,
                                    y,
                                    AND(
                                        x<=E,
                                        y>=D
                                    )
                                )
                            )
                        )
                    )
                )
            )
        ),
        1
    )*(1-MUNIT(
        7
    )),
    "Y",
    ""))))
Excel solution 8 for Mark Overlapping Time Ranges, proposed by Oscar Mendez Roca Farell:
=LET(a,
     A2:A8,
     f,
     B2:B8,
     t,
     C2:C8,
     v,
     TOROW(
         f
     ),
     m,
     (t>=v)*((f
Excel solution 9 for Mark Overlapping Time Ranges, proposed by Sunny Baggu:
=LET(
 i,
     A2:A8,
    
 f,
     B2:B8,
    
 t,
     C2:C8,
    
 v,
     IF(
 MAKEARRAY(
 ROWS(
     i
 ),
    
 ROWS(
     i
 ),
    
 LAMBDA(r,
     c,
    
 INDEX((INDEX(
     f,
      r,
      1
 ) <= t) * (INDEX(
     t,
      r,
      1
 ) >= f) * (r <> c),
     c)
 )
 ),
    
 "Y",
    
 ""
 ),
    
 VSTACK(
     HSTACK(
         "",
          TOROW(
     i
 )
     ),
      HSTACK(
          i,
           v
      )
 )
)
Excel solution 10 for Mark Overlapping Time Ranges, proposed by LEONARD OCHEA 🇷🇴:
=LET(x,
    A2:A8,
    i,
    B2:B8,
    j,
    C2:C8,
    t,
    TOROW(
        x
    ),
    VSTACK(HSTACK(
        "",
        t
    ),
    HSTACK(x,
    IF((j>=TOROW(
        i
    ))*(TOROW(
        j
    )>=i)*(x<>t),
    "Y",
    ""))))
=LET(x,
    A2:A8,
    t,
    TOROW(
        x
    ),
    p,
    C2:C8>=TOROW(
        B2:B8
    ),
    VSTACK(HSTACK(
        "",
        t
    ),
    HSTACK(x,
    IF(p*TRANSPOSE(
        p
    )*(x<>t),
    "Y",
    ""))))
Excel solution 11 for Mark Overlapping Time Ranges, proposed by Andy Heybruch:
=LET(
 _task,
    A2:A8,
    
 _from,
    B2:B8,
    
 _to,
    C2:C8,
    
 _ans,
    IF(
 (_task<>TOROW(
     _task
 ))*
 (_from<=TOROW(
     _to
 ))*
 (_to>=TOROW(
     _from
 )),
    
 "Y",
    ""),
    
 HSTACK(
     VSTACK(
         "",
         _task
     ),
     VSTACK(
         TOROW(
     _task
 ),
         _ans
     )
 ))
Excel solution 12 for Mark Overlapping Time Ranges, proposed by Sandeep Marwal:
=LET(
    a,
    B2:C8,
    b,
    A2:A8,
    c,
    HSTACK(
        "",
        TRANSPOSE(
            b
        )
    ),
    VSTACK(
        c,
        HSTACK(
            b,
            MAKEARRAY(
                7,
                7,
                LAMBDA(
                    r,
                    c,
                    IFS(
                        r=c,
                        "",
                        TRUE,
                        IF(
                            OR(
                                AND(
                                    INDEX(
                                        a,
                                        r,
                                        1
                                    )INDEX(
                                        a,
                                        c,
                                        2
                                    ),
                                    INDEX(
                                        a,
                                        r,
                                        2
                                    )>INDEX(
                                        a,
                                        c,
                                        2
                                    )
                                )
                            ),
                            "",
                            "Y"
                        )
                    )
                )
            )
        )
    )
)
Excel solution 13 for Mark Overlapping Time Ranges, proposed by LUIS FLORENTINO COUTO CORTEGOSO:
=IF((((C2:C8-TOROW(B2:B8))*(TOROW(C2:C8)-B2:B8))>0)*(1-MUNIT(ROWS(A2:A8))),"Y","")
Excel solution 14 for Mark Overlapping Time Ranges, proposed by Tyler Cameron:
=LET(a,
    B2:C8*1440,
    b,
    A2:A8,
    c,
    MAKEARRAY(7,
    7,
    LAMBDA(r,
    c,
    LET(t,
    INDEX(
        a,
        r,
        {1,
        2}
    ),
    u,
    TOCOL(
        INDEX(
            a,
            c,
            {1,
            2}
        )
    ),
    b,
    IF(SUM(--(t=u))>0,
    1,
    SUM(--(t>u))),
    IF(
        r=c,
        "",
        IF(
            AND(
                b>0,
                b<4
            ),
            "Y",
            ""
        )
    )))),
    HSTACK(
        VSTACK(
            {""},
            b
        ),
        VSTACK(
            TOROW(
                b
            ),
            c
        )
    ))
Excel solution 15 for Mark Overlapping Time Ranges, proposed by Caroline Blake:
=LET(a,
    A2:C8,
    c,
    LAMBDA(
        x,
        CHOOSECOLS(
            a,
            x
        )
    ),
    r,
    LAMBDA(
        x,
        CHOOSEROWS(
            TRANSPOSE(
                a
            ),
            x
        )
    ),
    HSTACK(VSTACK(
        "",
        c(
            1
        )
    ),
    VSTACK(r(
            1
        ),
    IF(((r(
        2
    )>=c(
        2
    ))+(r(
        3
    )>=c(
        2
    )))*((r(
        2
    )<=c(
        3
    ))+(r(
        3
    )<=c(
        3
    )))*(c(
        2
    )<>r(
        2
    )),
    "Y",
    ""))))
Excel solution 16 for Mark Overlapping Time Ranges, proposed by Caroline Blake:
=LET(a,
    B2:B8,
    _a1,
    C2:C8,
    b,
    TRANSPOSE(
        a
    ),
    c,
    TRANSPOSE(
        _a1
    ),
    
r,
    IF(ISERROR(FIND("TRUE",
    (b>=a)&(c>=a))),
    "",
    "Y"),
    
_r1,
    IF(ISERROR(FIND("TRUE",
    (b<=_a1)&(c<=_a1))),
    "",
    "Y"),
    
_r3,
    IF(
        r="Y",
        IF(
            _r1="Y",
            IF(
                a=b,
                "",
                "Y"
            ),
            ""
        ),
        ""
    ),
    
HSTACK(
    VSTACK(
        "",
        A2:A8
    ),
    VSTACK(
        TRANSPOSE(
            A2:A8
        ),
        _r3
    )
))
Excel solution 17 for Mark Overlapping Time Ranges, proposed by Will Freestone:
=LET(a,
    --(B2:B8<=TOROW(
        C2:C8
    )),
     t,
    A2:A8,
     b,
    a*TRANSPOSE(
        a
    ),
     VSTACK(
         HSTACK(
             "",
             TOROW(
                 t
             )
         ),
         HSTACK(
             t,
             IF(
                 MAKEARRAY(
                     7,
                     7,
                     LAMBDA(
                         r,
                         c,
                         IF(
                             r=c,
                             0,
                             INDEX(
                                 b,
                                 r,
                                 c
                             )
                         )
                     )
                 ),
                 "Y",
                 ""
             )
         )
     ))
Excel solution 18 for Mark Overlapping Time Ranges, proposed by Will Freestone:
=LET(a,
    --(B2:B8<=TOROW(
        C2:C8
    )),
     t,
    A2:A8,
     b,
    a*TRANSPOSE(
        a
    ),
     VSTACK(HSTACK(
         "",
         TOROW(
             t
         )
     ),
    HSTACK(t,
    IF(b*(1-MUNIT(
        7
    )),
    "Y",
    ""))))

Solving the challenge of Mark Overlapping Time Ranges with Python

Python solution 1 for Mark Overlapping Time Ranges, proposed by Konrad Gryczan, PhD:
import pandas as pd
import numpy as np
input = pd.read_excel("467 Overlapping Times.xlsx", usecols="A:C", nrows=7)
test = pd.read_excel("467 Overlapping Times.xlsx", usecols="E:L", nrows=8, skiprows=1)
test.columns = ['Task ID'] + list(test.columns[1:])
test = test.set_index('Task ID')
input['key'] = 0
input = input.merge(input, on='key').drop('key', axis=1)
input = input[input['Task ID_x'] != input['Task ID_y']]
input['overlap'] = (input['To Time_x'] >= input['From Time_y']) & (input['From Time_x'] <= input['To Time_y'])
input['overlap'] = input['overlap'].map({True: 'Y', False: np.nan})
input = input[['Task ID_x', 'Task ID_y', 'overlap']]
input = input.pivot(index='Task ID_x', columns='Task ID_y', values='overlap')
input.reset_index(drop=True, inplace=True)
input.fillna('', inplace=True)
test.reset_index(drop=True, inplace=True)
test.fillna('', inplace=True)
test.columns = input.columns
print(input.equals(test))
                    
                  

Solving the challenge of Mark Overlapping Time Ranges with Python in Excel

Python in Excel solution 1 for Mark Overlapping Time Ranges, proposed by Abdallah Ally:
import pandas as pd
from datetime import datetime, time, timedelta
# Function to generate time intervals
def time_intervals(start_time, end_time, interval=15):
 start_date = datetime(1900, 1, 1) # Arbitrary date
 start_time = datetime.combine(start_date, start_time)
 end_time = datetime.combine(start_date, end_time)
 times = []
 current_datetime = start_time
 while current_datetime <= end_time:
 times.append(current_datetime.time())
 current_datetime += timedelta(minutes=interval)
 return times
file_path = 'Excel_Challenge_467 - Overlapping Times.xlsx'
df = pd.read_excel(file_path, usecols='A:C', nrows=7)
# Perform data wrangling
df = df.set_index('Task ID', drop=True)
items = []
for i in df.index:
 item = [i]
 for j in df.index:
 a, b = df.loc[i, 'From Time':], df.loc[j, 'From Time':]
 if i == j:
 item.append('')
 else:
 intersect = any([x in time_intervals(*b) for x in time_intervals(*a)])
 item.append('Y' if intersect else '')
 items.append(item)
 
df = pd.DataFrame(items, columns=[''] + list(df.index)) 
df
                    
                  

Solving the challenge of Mark Overlapping Time Ranges with R

R solution 1 for Mark Overlapping Time Ranges, proposed by Konrad Gryczan, PhD:
library(tidyverse)
library(readxl)
input = read_excel("Excel/467 Overlapping Times.xlsx", range = "A1:C8")
test = read_excel("Excel/467 Overlapping Times.xlsx", range = "E2:L9") %>%
 select(`Task ID` = ...1, everything())
r1 = input %>%
 mutate(interval = interval(`From Time`, `To Time`)) %>%
 select(-`From Time`, -`To Time`) 
combinations = expand_grid(r1, r1, .name_repair = "unique") %>%
 filter(`Task ID...1` != `Task ID...3`) %>%
 mutate(overlap = ifelse(int_overlaps(interval...2, interval...4), "Y", NA_character_)) %>%
 select(`Task ID`, sort(colnames(.)))
identical(test, combinations)
# [1] TRUE
                    
                  
R solution 2 for Mark Overlapping Time Ranges, proposed by Anil Kumar Goyal:
library(readxl)
library(dplyr)
library(igraph)
df <- read_excel("Excel/Excel_Challenge_467 - Overlapping Times.xlsx", range = cell_cols(LETTERS[1:3]))
df |> 
 inner_join(df,
 join_by(`Task ID` < `Task ID`, 
 overlaps(`From Time`, `To Time`, `From Time`, `To Time`))) |> 
 select(from = `Task ID.x`, to = `Task ID.y`) |> 
 graph_from_data_frame(directed = FALSE, vertices = LETTERS[1:7]) |> 
 as_adjacency_matrix() |> 
 as.matrix() |> 
 as.data.frame() |> 
 tibble::rownames_to_column(" ") |> 
 mutate(across(A:G, ~ifelse(. == 1, "Y", " ")))
                    
                  

&&

Leave a Reply