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]); }
public void InitializationTest() { var d = new FlexibleDictionary <int, string> { [1] = "a" }; Assert.AreEqual("a", d[1]); Assert.AreEqual(1, d.Count); }
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[""]); }
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); }
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]); } }
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]); }
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); }
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); }
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())); }
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); }