Home » People Connection!

People Connection!

Solving People Connection challenge by Power Query, Power BI, Excel, Python and R

In the question table, direct connections between people are provided. Our task is to map these connections into a symmetric table, as shown in the result table. If two people are directly connected, enter a “1” in the corresponding cell. If there is no direct connection, list the people who form a bridge between the two individuals. For example, in the red cell, there is no direct connection between A and G. However, A is connected to C, C is connected to F, and F is connected to G. Therefore, the cell will display “C-F,” indicating the bridge connecting A and G.

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

Solving the challenge of People Connection! with Power Query

Power Query solution 1 for People Connection!, proposed by Kris Jaganah:
let
  A = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  B = List.Transform(Table.ToRows(A), each _{0} & _{1}), 
  C = List.Distinct(List.TransformMany(B, each Text.ToList(_), (u, v) => v)), 
  F = (s) =>
    [
      D = List.Accumulate(
        {1 .. 5}, 
        {s}, 
        (t, u) =>
          List.Distinct(
            List.TransformMany(
              t, 
              each List.Select(
                B, 
                (v) =>
                  Text.End(v, 1)
                    = Text.Start(Text.End(_, 1), 1) or Text.Start(v, 1)
                    = Text.End(_, 1)
              ), 
              (x, y) => x & Text.Remove(x & y, Text.ToList(x))
            )
          )
      ), 
      E = List.Transform(
        C, 
        each 
          let
            a = List.Select(List.Sort(D, each Text.Length(_)), (u) => Text.End(u, 1) = _){0}? ?? "-", 
            b = Text.Length(a), 
            c = 
              if b = 1 then
                a
              else if b = 2 then
                "1"
              else
                Text.Combine(List.RemoveLastN(List.Skip(Text.ToList(a))), "-")
          in
            c
      )
    ][E], 
  G = Table.FromRows(List.Transform(C, each {_} & F(_)), {""} & C)
in
  G
Power Query solution 2 for People Connection!, proposed by Kris Jaganah:
let
  A = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  B = List.TransformMany(Table.ToRows(A), each {_{0} & _{1}} & {_{1} & _{0}}, (_, w) => w), 
  C = List.Distinct(List.TransformMany(B, each Text.ToList(_), (_, u) => u)), 
  D = List.Transform(
    C, 
    (m) =>
      [
        a = List.Sort(
          List.Accumulate(
            {0 .. 5}, 
            {m}, 
            (x, y) =>
              List.Distinct(
                List.TransformMany(
                  x, 
                  each List.Select(B, (v) => Text.End(v, 1) = Text.End(_, 1)), 
                  (_, z) => _ & Text.Remove(z, Text.ToList(_))
                )
              )
          ), 
          (w) => Text.Length(w)
        ), 
        b = {m}
          & List.Transform(
            C, 
            (s) =>
              [
                p = Text.Remove(List.Select(a, each Text.End(_, 1) = s){0}? ?? "-", {s, m}), 
                q = (if p = "" then 1 else Text.Combine(Text.ToList(p), "-"))
              ][q]
          )
      ][b]
  ), 
  E = Table.FromRows(D, {" "} & C)
in
  E

Solving the challenge of People Connection! with Excel

Excel solution 1 for People Connection!, proposed by Bo Rydobon 🇹🇭:
=LET(
    p,
    B3:B11,
    q,
    C3:C11,
    pq,
    VSTACK(
        p,
        q
    ),
    qp,
    VSTACK(
        q,
        p
    ),
    u,
    SORT(
        UNIQUE(
            pq
        )
    ),
    v,
    TOROW(
        u
    ),    c,
    REDUCE(
        v,
        v,
        LAMBDA(
            a,
            i,
            UNIQUE(
                TOROW(
                    a&IF(
                        REGEXTEST(
                            a,
                            pq&"$"
                        )*ISERR(
                            FIND(
                                qp,
                                a
                            )
                        ),
                        "-"&qp,
                        ""
                    ),
                    3
                ),
                1
            )
        )
    ),    MAP(
        IFNA(
            u,
            v
        ),
        IFNA(
            v,
            u
        ),
        LAMBDA(
            i,
            j,
            IF(
                i=j,
                "-",
                LET(
                    x,
                    REGEXEXTRACT(
                        c,
                        "^"&i&"-K.*?(?=-?"&j&")"
                    ),
                    y,
                    @SORTBY(
                        x,
                        LEN(
                            x
                        )
                    ),
                    IF(
                        y="",
                        1,
                        y
                    )
                )
            )
        )
    )
)
Excel solution 2 for People Connection!, proposed by Bo Rydobon 🇹🇭:
=LET(p,
    B3:B11,
    q,
    C3:C11,
    pq,
    VSTACK(
        p,
        q
    ),
    qp,
    VSTACK(
        q,
        p
    ),
    u,
    SORT(
        UNIQUE(
            pq
        )
    ),
    v,
    TOROW(
        u
    ),b,
    LAMBDA(b,
    a,
    LET(n,
    ROWS(
        a
    ),
    IF(n=1,
    a&IFERROR("-"&FILTER(pq,
    (TEXTAFTER(
        "-"&a,
        "-",
        -1
    )=qp)*ISERR(
        FIND(
            pq,
            a
        )
    )),
    ""),
    VSTACK(
        b(
            b,
            TAKE(
                a,
                n/2
            )
        ),
        b(
            b,
            DROP(
                a,
                n/2
            )
        )
    )))),c,
    REDUCE(
        u,
        u,
        LAMBDA(
            a,
            _,
            b(
                b,
                a
            )
        )
    ),
    MAP(
        IFNA(
            u,
            v
        ),
        IFNA(
            v,
            u
        ),
        LAMBDA(
            i,
            j,
            LET(
                x,
                MID(
                    TEXTBEFORE(
                        TEXTAFTER(
                            c,
                            i
                        ),
                        "-"&j
                    ),
                    2,
                    99
                ),
                y,
                @SORTBY(
                    x,
                    LEN(
                        x
                    )
                ),
                IFNA(
                    IF(
                        y="",
                        1,
                        y
                    ),
                    "-"
                )
            )
        )
    ))
Excel solution 3 for People Connection!, proposed by Kris Jaganah:
=LET(a,
    B3:B11,
    b,
    C3:C11,
    c,
    UNIQUE(
        TOCOL(
            B3:C11
        )
    ),
    d,
    {0;1;2;3;4;5},
    t,
    TOROW(
        c
    ),
    HSTACK(VSTACK(
        "",
        c
    ),
    REDUCE(t,
    c,
    LAMBDA(k,
    l,
    VSTACK(k,
    LET(e,
    UNIQUE(
        TOCOL(
            REDUCE(
                l,
                d,
                LAMBDA(
                    x,
                    y,
                    HSTACK(
                        x,
                        TOROW(
                            IFS(
                                a=RIGHT(
                                    x
                                ),
                                x&b,
                                b=RIGHT(
                                    x
                                ),
                                x&a
                            ),
                            3
                        )
                    )
                )
            )
        )
    ),
    f,
    MAP(
        e,
        LAMBDA(
            v,
            CONCAT(
                UNIQUE(
                    REGEXEXTRACT(
                        v,
                        "[A-Z+]",
                        1
                    ),
                    1
                )
            )
        )
    ),
    g,
    LEN(
        f
    ),
    h,
    REDUCE(zz,
    d,
    LAMBDA(v,
    w,
    IFERROR(v,
    MAP(t,
    LAMBDA(v,
    TAKE(FILTER(f,
    (v=RIGHT(
        f
    ))*(g=w+1)),
    1)))))),
    i,
    LEN(
        h
    ),
    j,
    IFS(
        i=1,
        "-",
        i=2,
        1,
        1,
        MID(
            h,
            2,
            i-2
        )
    ),
    MAP(
        j,
        LAMBDA(
            s,
            TEXTJOIN(
                "-",
                ,
                REGEXEXTRACT(
                    s,
                    "[A-Z-+1]",
                    1
                )
            )
        )
    )))))))
Excel solution 4 for People Connection!, proposed by Diarmuid Early:
=LET(from,
    B3:B11,
    to,
    C3:C11,
    people,
    SORT(
        UNIQUE(
            VSTACK(
                from,
                to
            )
        )
    ), num,
    ROWS(
        people
    ), oneway,
    COUNTIFS(
        from,
        people,
        to,
        TOROW(
        people
    )
    ), matrix,
    oneway+TRANSPOSE(
        oneway
    ), pathOneStep,
    IF(
        matrix,
        people&"-"&TOROW(
        people
    ),
        0
    ),
 fullPath,
    REDUCE(pathOneStep,
    SEQUENCE(
        num
    ),
    LAMBDA(a,
    v,
    LET(
 numMat,
    --(a<>0),
    nxtCon,
    (--(MMULT(
        matrix,
        numMat
    )>0)>numMat)-MUNIT(
        num
    ), nxtPath,
    MAKEARRAY(num,
    num,
    LAMBDA(r,
    c,
    IF(NOT(
        INDEX(
            nxtCon,
            r,
            c
        )
    ), INDEX(
     a,
     r,
     c
 ), LET(rw,
    TOCOL(
        INDEX(
            a,
            r,
            0
        )
    ), cl,
    INDEX(
        a,
        0,
        c
    ), hit,
    XMATCH(1,
    IF((rw<>0)*(cl<>0),
    LEN(
        rw
    )+LEN(
        cl
    ),
    ""),
    1), INDEX(
     rw,
     hit
 )&MID(
     INDEX(
         cl,
         hit
     ),
     2,
     99
 ))))), nxtPath))),
 out,
    IF(
        fullPath=0,
        "-",
        IF(
            LEN(
                fullPath
            )=3,
            1,
            SUBSTITUTE(
                SUBSTITUTE(
                    fullPath,
                    people&"-",
                    ""
                ),
                "-"&TOROW(
        people
    ),
                ""
            )
        )
    ), out)
Excel solution 5 for People Connection!, proposed by Jazen Cosby:
=0,
    "-",
    IF(
        LEN(
            fullPath
        )=3,
        1,
        SUBSTITUTE(
            SUBSTITUTE(
                fullPath,
                p&"-",
                ""
            ),
            "-"&TOROW(
                p
            ),
            ""
        )
    )),out)
Excel solution 6 for People Connection!, proposed by Pieter de B.:
=LET(
    a,
    B3:C11,
    b,
    VSTACK(
        a,
        SORTBY(
            a,
            {2,
            1}
        )
    ),
    c,
    TAKE,
    u,
    UNIQUE(
        TOCOL(
            a
        )
    ),
    r,
    ROWS(
        u
    ),
    MAKEARRAY(
        r,
        r,
        LAMBDA(
            m,
            n,
            LET(
                p,
                INDEX(
                    u,
                    n,
                    1
                ),
                q,
                ,
                h,
                TEXTAFTER(
                    REDUCE(
                        INDEX(
                            u,
                            m,
                            1
                        ),
                        ROW(
            a
        ),
                        LAMBDA(
                            x,
                            _,
                            IFNA(
                                XLOOKUP(
                                    "*-"&p,
                                    x,
                                    x,
                                    ,
                                    2
                                ),
                                REDUCE(
                                    "",
                                    x,
                                    LAMBDA(
                                        v,
                                        w,
                                        VSTACK(
                                            v,
                                            w&FILTER(
                                                "-"&c(
                                                    b,
                                                    ,
                                                    -1
                                                ),
                                                c(
                                                    b,
                                                    ,
                                                    1
                                                )=TEXTAFTER(
                                                    "-"&w,
                                                    "-",
                                                    -1
                                                ),
                                                ""
                                            )
                                        )
                                    )
                                )
                            )
                        )
                    ),
                    "-"
                ),
                IFS(
                    m=n,
                    "-",
                    h=p,
                    1,
                    1,
                    TEXTBEFORE(
                        h,
                        "-",
                        -1
                    )
                )
            )
        )
    )
)
Excel solution 7 for People Connection!, proposed by Talia Cao, CPA:
=LET(
    s,
     B3:B11,
     e,
     C3:C11,     t,
     HSTACK(
         VSTACK(
             s,
             e
         ),
         VSTACK(
             e,
             s
         )
     ),     l,
     SORT(
         UNIQUE(
             TAKE(
                 t,
                 ,
                 1
             )
         )
     ),     i,
     ROWS(
         l
     ),    
     fxMinPath,
     LAMBDA(
         StartNode,
         EndNode,          LET(
              f,
               LAMBDA(
                   ME,
                   Path,
                   
                    LET(
                        NextNodes,
                         FILTER(
                             TAKE(
                                 t,
                                 ,
                                 -1
                             ),
                             TAKE(
                 t,
                 ,
                 1
             )=TEXTAFTER(
                 Path,
                 "-",
                 -1,
                 ,
                 1
             ),
                              ""
                         ),
                        
                         UNIQUE(
                             DROP(
                                 REDUCE(
                                     "",
                                     NextNodes,
                                     LAMBDA(
                                         a,
                                         n,
                                         
                                          VSTACK(
                                              a,
                                              
                                               IF(
                                                   ISNUMBER(
                                                       FIND(
                                                           n,
                                                            Path
                                                       )
                                                   ),
                                                    Path,
                                                   
                                                    IF(
                                                        n=EndNode,
                                                         Path&"-"&n,
                                                         ME(
                                                             ME,
                                                             Path&"-"&n
                                                         )
                                                    )
                                               )
                                          )
                                     )
                                 ),
                                 1
                             )
                         )
                    )
               ),
              
               FromStart,
               f(
                   f,
                   StartNode
               ),
              
               ToEnd,
                 FILTER(
                  FromStart,
                  TEXTAFTER(
                      FromStart,
                      "-",
                      -1
                  )=EndNode,
                  ""
              ),
              
               TEXTBEFORE(
                   TEXTAFTER(
                       @SORTBY(
                           ToEnd,
                           LEN(
                               ToEnd
                           )-LEN(
                               SUBSTITUTE(
                                   ToEnd,
                                   "-",
                                   ""
                               )
                           )
                       ),
                       "-"
                   ),
                   "-",
                   -1,
                   ,
                   ,
                   1
               )
          )
     ),    
     IF(
         MUNIT(
             i
         ),
         "-",
         MAKEARRAY(
             i,
             i,
             LAMBDA(
                 r,
                 c,
                 IFNA(
                     fxMinPath(
                         INDEX(
                             l,
                             r,
                             1
                         ),
                         INDEX(
                             l,
                             c,
                             1
                         )
                     ),
                     ""
                 )
             )
         )
     )
)

Solving the challenge of People Connection! with Python

Python solution 1 for People Connection!, proposed by Konrad Gryczan, PhD:
import pandas as pd
import networkx as nx

path = "CH-200People Connection.xlsx"
input = pd.read_excel(path, usecols="B:C", skiprows=1, nrows=9)
test = pd.read_excel(path, usecols="E:M", skiprows=1, nrows=9)

G = nx.from_pandas_edgelist(input, source='Person 1', target='Person 2', create_using=nx.Graph())

all_people = sorted(set(input['Person 1']).union(set(input['Person 2'])))
all_com = pd.DataFrame([(a1, a2) for a1 in all_people for a2 in all_people], columns=['a1', 'a2'])

def shortest_path(a1, a2, G):
 if a1 == a2:
 return "-"
 try:
 path = nx.shortest_path(G, source=a1, target=a2)
 if len(path) <= 2:
 return "1"
 nodes_between = path[1:-1]
 return "-".join(nodes_between)
 except nx.NetworkXNoPath:
 return "1"

all_com['path'] = all_com.apply(lambda row: shortest_path(row['a1'], row['a2'], G), axis=1)
result = all_com.pivot(index='a2', columns='a1', values='path')
print(result)
print(test)

# Discrepancies because of incosistent node sorting, but the paths are correct

Solving the challenge of People Connection! with Python in Excel

Python in Excel solution 1 for People Connection!, proposed by Alejandro Campos:
df = xl("B2:C11", headers=True)
persons = sorted(set(df["Person 1"]) | set(df["Person 2"]))
symmetric_table = pd.DataFrame("-", index=persons, columns=persons)
graph = {p: [] for p in persons}
for p1, p2 in zip(df["Person 1"], df["Person 2"]):
 symmetric_table.loc[p1, p2] = symmetric_table.loc[p2, p1] = "1"
 graph[p1].append(p2)
 graph[p2].append(p1)
def find_paths(g, s, e, p=[]):
 p = p + [s]
 return [p] if s == e else sum((find_paths(g, n, e, p) for n in g[s] if n not in p), [])
for i, p1 in enumerate(persons):
 for p2 in persons[i+1:]:
 if symmetric_table.loc[p1, p2] != "1":
 paths = find_paths(graph, p1, p2)
 if paths:
 bridges = min(paths, key=len)[1:-1]
 if bridges:
 symmetric_table.loc[p1, p2] = symmetric_table.loc[p2, p1] = "-".join(bridges)
symmetric_table

Solving the challenge of People Connection! with R

R solution 1 for People Connection!, proposed by Konrad Gryczan, PhD:
library(tidyverse)
library(readxl)
library(igraph)

path = "files/CH-200People Connection.xlsx"
input = read_excel(path, range = "B2:C11")
test = read_excel(path, range = "E2:M10")

g = graph_from_data_frame(input, directed = FALSE)
all_people = sort(unique(c(input$`Person 1`, input$`Person 2`))) 
all_com = expand.grid(a1 = all_people, a2 = all_people, stringsAsFactors = F) 

shortest_path = function(a1, a2, g){
 if (a1 == a2) {
 return("-")
 }
 path = all_shortest_paths(g, from = a1, to = a2)
 if (length(path$res) == 0 || length(path$res[[1]]$name) <= 2) {
 return("1")
 }
 nodes_between = path$res[[1]]$name[-c(1, length(path$res[[1]]$name))]
 return(paste(nodes_between, collapse = "-"))
}

result = all_com %>%
 rowwise() %>%
 mutate(path = shortest_path(a1, a2, g)) %>%
 pivot_wider(names_from = a1, values_from = path)

print(result)
print(test)

Leave a Reply