示例#1
0
            public CircusProgram(IEnumerable <ProgramNodeDeclaration> programNodes)
            {
                var nodeDictionary = new FlexibleDictionary <string, ProgramTreeNode>();

                // Register all nodes
                foreach (var node in programNodes)
                {
                    nodeDictionary[node.Name] = new(new(node));
                }

                // Declare the relationships
                var availableChildren = new HashSet <string>(nodeDictionary.Keys);

                foreach (var node in programNodes)
                {
                    if (node.IsLeafNode)
                    {
                        continue;
                    }

                    foreach (var child in node.ChildrenNodes)
                    {
                        nodeDictionary[node.Name].AddChild(nodeDictionary[child]);
                        availableChildren.Remove(child);
                    }
                }

                // Identify the tree root
                var rootName = availableChildren.Single();

                programTree = new(nodeDictionary[rootName]);
            }
示例#2
0
        public void InitializationTest()
        {
            var d = new FlexibleDictionary <int, string>
            {
                [1] = "a"
            };

            Assert.AreEqual("a", d[1]);
            Assert.AreEqual(1, d.Count);
        }
示例#3
0
        public void AccessorTest()
        {
            var d     = new FlexibleDictionary <string, int>();
            int value = d[""];

            Assert.AreEqual(0, value);
            d["a"] = 5;
            Assert.AreEqual(5, d["a"]);
            d[""] = 3;
            Assert.AreEqual(3, d[""]);
        }
示例#4
0
        public void EnumerableInitializationTest()
        {
            var values       = new[] { 1, 4, 1, 6, 2, 2 };
            var uniqueValues = new[] { 1, 2, 4, 6 };
            var d            = new FlexibleDictionary <int, string>(values);

            foreach (var v in uniqueValues)
            {
                Assert.AreEqual(default(string), d[v]);
            }
            Assert.AreEqual(4, d.Count);
        }
示例#5
0
        public override ulong SolvePart1()
        {
            int targetWeight = packageWeights.Sum() / 3;

            GetMinMaxGroupSize(targetWeight, out int minGroupSize, out int maxGroupSize);

            // Start finding the groups
            int group1Size = minGroupSize;

            PackageGroup bestGroup   = null;
            ulong        bestGroupQE = ulong.MaxValue;

            var packageWeightsSet = new HashSet <int>(packageWeights);
            var groupDictionary   = new FlexibleDictionary <int, HashSet <int>[]>();

            while (true)
            {
                foreach (var group1 in GetGroups(group1Size))
                {
                    var remainingWeights = new HashSet <int>(packageWeightsSet);
                    remainingWeights.ExceptWith(group1);
                    int maxGroup2Size = maxGroupSize - (packageWeightsSet.Count - remainingWeights.Count);

                    for (int group2Size = minGroupSize; group2Size < maxGroup2Size; group2Size++)
                    {
                        if (GetGroups(group2Size).Any(group => !remainingWeights.Overlaps(group)))
                        {
                            EvaluateBestGroup(new(group1), ref bestGroup, ref bestGroupQE);
                            break;
                        }
                    }
                }

                if (bestGroup is not null)
                {
                    return(bestGroupQE);
                }

                group1Size++;
            }

            IEnumerable <HashSet <int> > GetGroups(int size)
            {
                if (!groupDictionary.ContainsKey(size))
                {
                    groupDictionary[size] = FindGroups(size, targetWeight, packageWeights);
                }
                return(groupDictionary[size]);
            }
        }
示例#6
0
        public override long SolvePart2()
        {
            var indexedIDs = new FlexibleDictionary <int, int>();

            for (int i = 0; i < busIDs.Length; i++)
            {
                if (busIDs[i] == 0)
                {
                    continue;
                }

                indexedIDs[busIDs[i]] = i;
            }

            var sortedIDs = busIDs.Where(id => id > 0).ToArray();

            Array.Sort(sortedIDs, CompareDescending);
            var sortedIDOffsets = sortedIDs.Select(id => indexedIDs[id]).ToArray();

            long max0 = sortedIDs[0];

            long velocity         = max0;
            long currentTimestamp = 0;

            int lockedMultipliers = 1;

            int offsetDiff = sortedIDOffsets[lockedMultipliers] - sortedIDOffsets[0];

            while (lockedMultipliers < sortedIDs.Length)
            {
                currentTimestamp += velocity;

                while ((currentTimestamp + offsetDiff) % sortedIDs[lockedMultipliers] == 0)
                {
                    // Register another locked multiplier
                    velocity = MathFunctions.LCM(velocity, sortedIDs[lockedMultipliers]);

                    lockedMultipliers++;
                    if (lockedMultipliers >= sortedIDs.Length)
                    {
                        break;
                    }

                    offsetDiff = sortedIDOffsets[lockedMultipliers] - sortedIDOffsets[0];
                }
            }

            return(currentTimestamp - sortedIDOffsets[0]);
        }
示例#7
0
        public void TryGetValueTest()
        {
            var d = new FlexibleDictionary <string, int>
            {
                ["a"] = 2,
            };

            bool found = d.TryGetValue("fsad", out int value);

            Assert.IsFalse(found);
            Assert.AreEqual(0, value);

            found = d.TryGetValue("a", out value);
            Assert.IsTrue(found);
            Assert.AreEqual(2, value);
        }
示例#8
0
            public CircularCupArrangement(int[] originalCups, bool addExtraCups = true)
            {
                labels             = new(originalCups);
                currentSelectedCup = labels.Head;

                if (addExtraCups)
                {
                    for (int i = originalCups.Length + 1; i <= CupCount; i++)
                    {
                        labels.Add(i);
                    }
                }

                hashedLabels = new(labels.Count);
                var currentNode = labels.Head;

                do
                {
                    hashedLabels[currentNode.Value] = currentNode;
                    currentNode = currentNode.Next;
                }while (currentNode != labels.Head);
            }
示例#9
0
            public string GetFinalProgramOrder(int danceCount = 1)
            {
                var result            = new ProgramArrangement();
                var arrangements      = new FlexibleDictionary <ulong, int?>();
                var roundArrangements = new FlexibleDictionary <int, ulong>();

                for (int i = 0; i < danceCount; i++)
                {
                    foreach (var move in moves)
                    {
                        move.Operate(result);
                    }

                    ulong arrangementCode = result.GetCurrentArrangementCode();
                    if (arrangements[arrangementCode] is int firstOccurrence)
                    {
                        // Skip remaining moves
                        int loopSize         = firstOccurrence - i;
                        int offset           = firstOccurrence - loopSize;
                        int finalLoopedIndex = (danceCount - offset) % loopSize - 1;
                        return(ProgramArrangement.FromArrangementCode(roundArrangements[finalLoopedIndex]));
                    }
                    else
                    {
                        arrangements[arrangementCode] = i;
                        roundArrangements[i]          = arrangementCode;
                    }
#if DEBUG
                    if (i % 1000 is 0)
                    {
                        Console.WriteLine($"Dance performed {i} times");
                    }
#endif
                }

                return(new(result.ConstructArray()));
            }
示例#10
0
            public int GetCountAfterRemovingCollsions()
            {
                var remaining        = new HashSet <MovableParticle>(particles.Select(MovableParticle.FromParticle));
                int previousCount    = remaining.Count;
                int ignoredParticles = 0;

                var locations          = new FlexibleDictionary <Location3D, MovableParticle>();
                int nonCollidingRounds = 0;

                while (remaining.Any())
                {
                    nonCollidingRounds++;

                    // ToArray is sadly necessary
                    foreach (var particle in remaining.ToArray())
                    {
                        particle.Iterate();
                        var position = particle.Position;

                        // Identify collision and remove the colliding particles
                        if (!locations.TryAdd(position, particle))
                        {
                            remaining.Remove(locations[position]);
                            remaining.Remove(particle);
                            nonCollidingRounds = 0;
                        }
                    }

                    locations.Clear();

                    const int collisionRoundThreshold = 12;

                    // No collisions in the past rounds; must evaluate the relationships between the particles
                    // to ignore the ones that will never collide
                    if (nonCollidingRounds > collisionRoundThreshold)
                    {
                        var approachMap = new FlexibleListDictionary <MovableParticle, MovableParticle>();

                        var remainingArray = remaining.ToArray();
                        for (int i = 0; i < remainingArray.Length; i++)
                        {
                            var a = remainingArray[i];

                            for (int j = i + 1; j < remainingArray.Length; j++)
                            {
                                var b = remainingArray[j];

                                if (!a.Approaches(b))
                                {
                                    continue;
                                }

                                approachMap[a].Add(b);
                                approachMap[b].Add(a);
                            }
                        }

                        // Eliminate disconnected particles
                        foreach (var particle in remainingArray)
                        {
                            if (approachMap.ContainsKey(particle))
                            {
                                continue;
                            }

                            remaining.Remove(particle);
                            ignoredParticles++;
                        }

                        // Reset the counter since the particles were reduced
                        nonCollidingRounds = 0;
                    }
                }

                return(ignoredParticles);
            }