private void FillVoxelPoint(Point3D voxelPoint)
        {
            var bot         = _scene.GetFirstBot();
            var botVector   = Vector3D.FromPoint(bot.Current);
            var voxelVector = Vector3D.FromPoint(voxelPoint);
            var dsuIndex    = GetPointDSUIndex(voxelPoint);

            if (voxelPoint.Y == 0)
            {
                // foreach (var point in FilledAdjacent(voxelPoint))
                // {
                //     var p = GetPointDSUIndex(point);
                //     _dsu.Union(p, dsuIndex);
                // }
                _dsu.Union(0, dsuIndex);
            }
            else
            {
                var adjacentFilled = FilledAdjacent(voxelPoint).ToList();
                if (adjacentFilled.Count > 0)
                {
                    foreach (var point in adjacentFilled)
                    {
                        var p = GetPointDSUIndex(point);
                        _dsu.Union(p, dsuIndex);
                    }
                }
                else
                {
                    if (_scene.SceneState.HarmonicsMode == HarmonicsMode.Grounded)
                    {
                        ApplyCommand(new FlipCommand());
                    }
                }
            }

            _voxelsFilled += 1;
            ApplyCommand(new FillCommand(voxelVector - botVector));

            if (_voxelsFilled == _dsu.SizeOf(0) - 2)
            {
                if (_scene.SceneState.HarmonicsMode == HarmonicsMode.Floating)
                {
                    ApplyCommand(new FlipCommand());
                }
            }
            else
            {
                if (_scene.SceneState.HarmonicsMode == HarmonicsMode.Grounded)
                {
                    ApplyCommand(new FlipCommand());
                }
            }
        }
Beispiel #2
0
 static void Main()
 {
     string[] lines = File.ReadAllLines("dsu.in");
     int n = int.Parse(lines[0]);
     DSU dsu = new DSU();
     for (int i = 1; i <= n; ++i)
         dsu.AddSingleItem(i);
     StreamWriter sw = new StreamWriter("dsu.out");
     foreach (string s in lines.Skip(1))
     {
         string[] parts = s.Split(' ');
         if (parts[0] == "union")
         {
             int a = int.Parse(parts[1]) - 1,
                 b = int.Parse(parts[2]) - 1;
             dsu.Union(a,b);
         }
         else
         if (parts[0] == "get")
         {
             int a = int.Parse(parts[1]) - 1;
             DSU.DsuSet x = dsu.Get(a);
             sw.WriteLine("{0} {1} {2}", x.Min, x.Max, x.Count);
         }
     }
     sw.Close();
 }
Beispiel #3
0
        public IList <int> NumIslands2(int rows, int cols, int[,] positions)
        {
            var dsu    = new DSU(rows * cols);
            var result = new List <int>();

            int GetIndx(int r, int c) => r * cols + c;

            for (var i = 0; i < positions.GetLength(0); i++)
            {
                var r    = positions[i, 0];
                var c    = positions[i, 1];
                var indx = GetIndx(r, c);

                dsu.Set(indx);

                var up = GetIndx(r - 1, c);
                if (r - 1 >= 0 && dsu.IsSet(up))
                {
                    dsu.Union(indx, up);
                }

                var down = GetIndx(r + 1, c);
                if (r + 1 < rows && dsu.IsSet(down))
                {
                    dsu.Union(indx, down);
                }

                var left = GetIndx(r, c - 1);
                if (c - 1 >= 0 && dsu.IsSet(left))
                {
                    dsu.Union(indx, left);
                }

                var right = GetIndx(r, c + 1);
                if (c + 1 < cols && dsu.IsSet(right))
                {
                    dsu.Union(indx, right);
                }

                result.Add(dsu.GetCount());
            }

            return(result);
        }
Beispiel #4
0
        /// <summary>
        /// Nov. 19, 2020
        /// Union find algorithm
        /// study code
        /// https://leetcode.com/problems/sentence-similarity-ii/solution/
        /// Time complexity:
        /// Time Complexity: O(N log P + P), where N is the maximum length of words1 and words2,
        /// and P is the length of pairs. If we used union-by-rank, this complexity improves to
        /// O(N * a(P) + P), close to O(N + P), where α is the Inverse-Ackermann function.
        /// </summary>
        /// <param name="words1"></param>
        /// <param name="words2"></param>
        /// <param name="pairs"></param>
        /// <returns></returns>
        public bool AreSentencesSimilarTwo(string[] words1, string[] words2, IList <IList <string> > pairs)
        {
            var length1 = words1.Length;
            var length2 = words2.Length;
            var pLength = pairs.Count;

            if (length1 != length2)
            {
                return(false);
            }

            // index -> indexMap better name?
            var indexMap = new Dictionary <string, int>();

            int count = 0;

            var dsu = new DSU(2 * pLength);

            foreach (var pair in pairs)
            {
                // go through two words in one pair
                foreach (var p in pair)
                {
                    if (!indexMap.ContainsKey(p))
                    {
                        indexMap.Add(p, count++);
                    }
                }

                dsu.Union(indexMap[pair[0]], indexMap[pair[1]]);
            }

            for (int i = 0; i < length1; ++i)
            {
                var w1 = words1[i];
                var w2 = words2[i];

                if (w1.CompareTo(w2) == 0)
                {
                    continue;
                }

                if (!indexMap.ContainsKey(w1) ||
                    !indexMap.ContainsKey(w2) ||
                    dsu.Find(indexMap[w1]) != dsu.Find(indexMap[w2]))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #5
0
        public int[] FindRedundantConnection2(int[][] edges)
        {
            DSU = new DSU(edges.Length + 1);

            foreach (int[] edge in edges)
            {
                if (DSU.Union(edge[0], edge[1]))
                {
                    return(edge);
                }
            }
            return(edges[0]);
        }
Beispiel #6
0
    private int[] FindRedundantConnection(int[][] edges)
    {
        DSU dsu = new DSU(edges.Length);

        foreach (int[] edge in edges)
        {
            if (!dsu.Union(edge[0], edge[1]))
            {
                return(edge);
            }
        }

        throw new ArgumentException("Invalid argument");
    }
Beispiel #7
0
    public int RemoveStones(int[][] stones)
    {
        var dsu = new DSU(20000);

        foreach (var stone in stones)
        {
            dsu.Union(stone[0], stone[1] + 10000);
        }
        var seen = new HashSet <int>();

        foreach (var stone in stones)
        {
            seen.Add(dsu.Find(stone[0]));
        }
        return(stones.Length - seen.Count);
    }
Beispiel #8
0
    private int MinCostToConnectNodes(int N, int[][] connections)
    {
        Array.Sort(connections, (a, b) => a[2] - b[2]);

        DSU dsu  = new DSU(N + 1);
        int cost = 0;

        foreach (int[] arr in connections)
        {
            if (!dsu.Union(arr[0], arr[1]))
            {
                cost += arr[2];
            }
        }

        return(dsu.Count == 2 ? cost : -1);
    }
Beispiel #9
0
        public IList <IList <string> > AccountsMerge(IList <IList <string> > accounts)
        {
            EmailToId   = new Dictionary <string, int>();
            EmailToName = new Dictionary <string, string>();

            foreach (var account in accounts)
            {
                if (account.Count < 2)
                {
                    continue;
                }

                var name = account[0];
                for (var i = 1; i < account.Count; i++)
                {
                    if (!EmailToId.ContainsKey(account[i]))
                    {
                        var id = EmailToId.Count;
                        EmailToId[account[i]]   = id;
                        EmailToName[account[i]] = name;
                    }
                }
            }

            var totalAccounts = EmailToId.Count;

            DSU = new DSU(totalAccounts);

            foreach (var account in accounts)
            {
                // var name = account[0];
                for (var i = 1; i < account.Count - 1; i++)
                {
                    var id1 = EmailToId[account[i]];
                    var id2 = EmailToId[account[i + 1]];

                    if (id1 != id2)
                    {
                        DSU.Union(id1, id2);
                    }
                }
            }

            var result = new Dictionary <int, List <string> >();

            foreach (var email in EmailToName.Keys)
            {
                int index = DSU.Find(EmailToId[email]);
                if (result.TryGetValue(index, out var list))
                {
                    list.Add(email);
                }
                else
                {
                    result[index] = new List <string> {
                        email
                    };
                }
            }
            foreach (var emails in result.Values)
            {
                emails.Sort((x, y) =>
                {
                    var i = 0;
                    while (i < x.Length && i < y.Length)
                    {
                        if (x[i] != y[i])
                        {
                            return(x[i].CompareTo(y[i]));
                        }
                        i++;
                    }
                    return(x.Length.CompareTo(y.Length));
                });
                emails.Insert(0, EmailToName[emails[0]]);
            }
            return(result.Values.ToList <IList <string> >());
        }