using System.Collections.Generic;
using System.Threading.Tasks;
public Name FullName { get; set; }
public Address Address { get; set; }
public override bool Equals(object obj)
return FullName.GetFullName() == ((Person)obj).FullName.GetFullName() && Address.GetFullAddress() == ((Person)obj).Address.GetFullAddress();
public string FirstName { get; set; }
public string LastName { get; set; }
public string GetFullName()
return $"{FirstName} {LastName}";
public string Street { get; set; }
public string City { get; set; }
public string GetFullAddress()
return $"{Street}, {City}";
public static Dictionary<string, List<Person>> names = new Dictionary<string, List<Person>>();
public static Dictionary<string, List<Person>> address = new Dictionary<string, List<Person>>();
public static void Init(Person[] persons)
foreach (var p in persons)
if (names.ContainsKey(p.FullName.GetFullName()))
names[p.FullName.GetFullName()].Add(p);
names.Add(p.FullName.GetFullName(), new List<Person> { p });
if (address.ContainsKey(p.Address.GetFullAddress()))
address[p.Address.GetFullAddress()].Add(p);
address.Add(p.Address.GetFullAddress(), new List<Person> { p });
public static int FindRelation(Person personA, Person personB)
Queue<(Person, int)> pq = new Queue<(Person, int)>();
HashSet<Person> visitedNames = new HashSet<Person>();
HashSet<Person> visitedAdr = new HashSet<Person>();
HashSet<Person> visited = new HashSet<Person>();
pq.Enqueue((personA, 0));
var (currentPerson, distance) = pq.Dequeue();
if (!visited.Contains(currentPerson))
visited.Add(currentPerson);
if (currentPerson.Equals(personB))
if (!visitedNames.Contains(currentPerson))
visitedNames.Add(currentPerson);
foreach (Person pName in names[currentPerson.FullName.GetFullName()])
pq.Enqueue((pName, distance + 1));
if (!visitedAdr.Contains(currentPerson))
visitedAdr.Add(currentPerson);
foreach (Person pAdrr in address[currentPerson.Address.GetFullAddress()])
pq.Enqueue((pAdrr, distance + 1));
static void Main(string[] args)
new Person() { FullName = new Name() { FirstName = "John", LastName ="John"}, Address = new Address { City = "123 Fake st.",Street = "123 Fake st." } },
new Person() { FullName = new Name() { FirstName = "Alice", LastName ="Alice"}, Address = new Address { City = "123 Fake st.",Street = "123 Fake st." }},
new Person() { FullName = new Name() { FirstName = "Alice", LastName ="Alice"}, Address = new Address { City = "456 Fake st.",Street = "456 Fake st." }},
new Person() { FullName = new Name() { FirstName = "Bob", LastName ="Bob"}, Address = new Address { City = "456 Fake st.",Street = "456 Fake st." }}};
int result = FindRelation(
new Person() { FullName = new Name() { FirstName = "John", LastName = "John" }, Address = new Address { City = "123 Fake st.", Street = "123 Fake st." } },
new Person() { FullName = new Name() { FirstName = "Bob", LastName = "Bob" }, Address = new Address { City = "456 Fake st.", Street = "456 Fake st." } });
Console.WriteLine("FindRelation: " + result);