static void Main(string[] args) { // string path = @"\clustering_big.txt"; string path = Directory.GetCurrentDirectory() + @"\clustering_big.txt"; string[] lines = File.ReadAllLines(path); NodeValues[] _nodeValues = new NodeValues[lines.Length + 1]; int index = 0; int[] _parentArray = new int[_nodeValues.Length + 1]; Hashtable _groupSizes = new Hashtable(); uint[] bitMasksHammingDistance_1 = new uint[24]; uint[] bitMasksHammingDistance_2 = new uint[276]; int _noOfNodes = _nodeValues.Length - 1; foreach (var s in lines) { index++; int pow = 23; string[] bits = s.TrimEnd(' ').Split(' '); _nodeValues[index] = new NodeValues(); foreach (var b in bits) { _nodeValues[index].node = index; _nodeValues[index].value += (uint)(Convert.ToInt16(b) * Math.Pow(2, pow)); pow--; } } //filling the values in the bitmasks for hamming distance 1 for (int i = 0; i < 24; i++) { bitMasksHammingDistance_1[i] = (uint)Math.Pow(2, i); } index = 0; //filling the values in the bitmasks for hamming distance 2 for (int i = 0; i < 23; i++) { for (int j = i + 1; j < 24; j++) { bitMasksHammingDistance_2[index] = (uint)(Math.Pow(2, i) + Math.Pow(2, j)); index++; } } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); QuickSort(1, _nodeValues.Length - 1); uint _max = _nodeValues[_nodeValues.Length - 1].value; for (int i = 1; i < _nodeValues.Length; i++) { int node1 = _nodeValues[i].node; uint _value1 = _nodeValues[i].value; uint _valueToFind = _value1; index = i + 1; int _leader1; int _leader2; while (index < _nodeValues.Length && _nodeValues[index].value == _valueToFind) { _leader1 = FindLeader(node1); _leader2 = FindLeader(_nodeValues[index].node); if (_leader1 != _leader2) { Union(_leader1, _leader2); _noOfNodes--; } index++; } for (int j = 0; j < 24; j++) { _valueToFind = _value1 ^ bitMasksHammingDistance_1[j]; if (_valueToFind <= _max) { int node2 = FindValue(1, _nodeValues.Length - 1, _valueToFind); if (node2 != 0) { _leader1 = FindLeader(node1); _leader2 = FindLeader(node2); if (_leader1 != _leader2) { Union(_leader1, _leader2); _noOfNodes--; } } } } for (int j = 0; j < 276; j++) { _valueToFind = _value1 ^ bitMasksHammingDistance_2[j]; if (_valueToFind <= _max) { int node2 = FindValue(1, _nodeValues.Length - 1, _valueToFind); if (node2 != 0) { _leader1 = FindLeader(node1); _leader2 = FindLeader(node2); if (_leader1 != _leader2) { Union(_leader1, _leader2); _noOfNodes--; } } } } } Console.WriteLine("ans is {0}", _noOfNodes); Console.WriteLine("time elapsed is {0}", stopwatch.ElapsedMilliseconds); void Union(int _lead1, int _lead2) { int _grpSize1 = _groupSizes.ContainsKey(_lead1) ? (int)_groupSizes[_lead1] : 1; int _grpSize2 = _groupSizes.ContainsKey(_lead2) ? (int)_groupSizes[_lead2] : 1; if (_grpSize1 > _grpSize2) { _parentArray[_lead2] = _lead1; _groupSizes[_lead1] = _grpSize1 + _grpSize2; } else { if (_grpSize1 == 1 && _grpSize2 == 1) { _groupSizes.Add(_lead2, 2); _parentArray[_lead1] = _lead2; } else { _parentArray[_lead1] = _lead2; _groupSizes[_lead2] = _grpSize2 + _grpSize1; } } } int FindLeader(int node) { while (_parentArray[node] != 0) { node = _parentArray[node]; } return(node); } int FindValue(int start_pos, int last_pos, uint _value) { int len = last_pos - start_pos + 1; if (len > 1) { int mid = start_pos + (len / 2); if (_value < _nodeValues[mid].value) { return(FindValue(start_pos, mid - 1, _value)); } else if (_value > _nodeValues[mid].value) { return(FindValue(mid + 1, last_pos, _value)); } else { return(_nodeValues[mid].node); } } else { if (_nodeValues[start_pos].value == _value) { return(_nodeValues[start_pos].node); } else { return(0); } } } void QuickSort(int start_pos, int last_pos) { int len = last_pos - start_pos + 1; if (len > 1) { int i = start_pos; uint pivot = _nodeValues[start_pos].value; for (int j = start_pos + 1; j <= last_pos; j++) { if (_nodeValues[j].value < pivot) { Swap(i + 1, j); i++; } } Swap(i, start_pos); QuickSort(start_pos, i - 1); QuickSort(i + 1, last_pos); } } void Swap(int i, int j) { NodeValues temp = _nodeValues[i]; _nodeValues[i] = _nodeValues[j]; _nodeValues[j] = temp; } Console.ReadKey(); }