using System;
using System.Collections.Generic;
using System.Linq;
class MainClass {
static void Main()
{
var list = new List<Device>();
list.Add(new Device() {Token1="a", Token2 = 3});
list.Add(new Device() {Token1="b", Token2 = 4});
list.Add(new Device() {Token1="a", Token2 = 6});
list.Add(new Device() {Token1="b", Token2 = 3});
list.Add(new Device() {Token1="c", Token2 = 4});
list.Add(new Device() {Token1="f", Token2 = 8});
list.Add(new Device() {Token1="g", Token2 = 6});
list.Add(new Device() {Token1="c", Token2 = 9});
list.Add(new Device() {Token1="k", Token2 = 12});
var count = GetUniqueDevices(list);
Console.WriteLine(count);
}
public static int GetUniqueDevices(IList<Device> devices)
{
var set = new Dictionary<string, Device>();
var graph = new Dictionary<string, HashSet<string>>();
for(int i = 0; i < devices.Count; i++)
{
set.Add(devices[i].GetHash(), devices[i]);
for(int j = i + 1; j < devices.Count; j++)
{
if(!devices[i].IsEqual(devices[j]))
continue;
// build graph
if(graph.ContainsKey(devices[i].GetHash()))
graph[devices[i].GetHash()].Add(devices[j].GetHash());
else graph.Add(devices[i].GetHash(), new HashSet<string>(){ devices[j].GetHash() });
if(graph.ContainsKey(devices[j].GetHash()))
graph[devices[j].GetHash()].Add(devices[i].GetHash());
else graph.Add(devices[j].GetHash(), new HashSet<string>(){ devices[i].GetHash() });
}
}
int count = 0;
var queue = new Queue<string>();
while(set.Count > 0)
{
queue.Enqueue(set.First().Key);
var visited = new HashSet<string>();
while(queue.Count > 0)
{
var loop = queue.Count;
for(int i = 0; i < loop; i++)
{
var hash = queue.Dequeue();
visited.Add(hash);
set.Remove(hash);
if(graph.ContainsKey(hash))
foreach(var child in graph[hash])
{
if(!visited.Contains(child))
queue.Enqueue(child);
}
}
}
count++;
}
return count;
}
public class Device
{
public string Token1;
public int Token2;
public Device(){}
public Device(string token1, int token2)
{
this.Token1 = token1;
this.Token2 = token2;
}
public bool IsEqual(Device device)
{
if(this.Token1 == device.Token1 || this.Token2 == device.Token2)
return true;
return false;
}
public string GetHash()
{
return $"{Token1}|{Token2}";
}
}
}