示例#1
0
            /// <summary>
            /// Calculates the distance in orbits between two objects,
            /// i.e. the number of "jumps" for A to get in the same orbit as B, and vice versa.
            /// </summary>
            /// <param name="obj1">The 1st object</param>
            /// <param name="obj2">The 2nd object</param>
            /// <returns></returns>
            public int OrbitalJumpsBetween(OrbitObject obj1, OrbitObject obj2)
            {
                List <OrbitObject> obj1ToHead    = obj1.ObjectsToHead();
                List <OrbitObject> obj2ToHead    = obj2.ObjectsToHead();
                OrbitObject        nearestObject = null;

                foreach (OrbitObject _obj1 in obj1ToHead)
                {
                    foreach (OrbitObject _obj2 in obj2ToHead)
                    {
                        if (_obj1 == _obj2)
                        {
                            nearestObject = _obj1;
                            break;
                        }
                    }
                    if (nearestObject != null)
                    {
                        break;
                    }
                }
                // This exception should never happen, because the head should be shared by all orbiting objects.
                if (nearestObject == null)
                {
                    throw new InvalidOperationException($"Objects {obj1} and {obj2} do not orbit a shared object.");
                }
                int obj1Distance = obj1ToHead.IndexOf(nearestObject) + 1;
                int obj2Distance = obj2ToHead.IndexOf(nearestObject) + 1;

                return(obj1Distance + obj2Distance);
            }
示例#2
0
            /// <summary>
            /// Takes a map entry like "FOO)BAR" and adds an OrbitObject named "BAR" to parent "FOO".
            /// - If "FOO" does not exist, it creates it.
            /// - If "BAR" exists, it makes "FOO" its parent node.
            /// - If "BAR" does not exist, it creates it, and sets "FOO" as its parent.
            /// </summary>
            /// <param name="entry">A map entry,e.g. "FOO)BAR"</param>
            /// <param name="delimiter">The character to use to split the values</param>
            public void ProcessMapEntry(string entry, char delimiter = ')')
            {
                string[]    orbit        = entry.Split(delimiter);
                string      orbitedName  = orbit[0];
                string      orbitingName = orbit[1];
                OrbitObject orbitedObj   = FindOrbitingObject(orbitedName);

                if (orbitedObj == null)
                {
                    orbitedObj = new OrbitObject(orbitedName);
                    AddObject(orbitedObj);
                }
                OrbitObject orbitingObj = FindOrbitingObject(orbitingName);

                if (orbitingObj != null)
                {
                    orbitingObj.SetParent(orbitedObj);
                    orbitedObj.AddChild(orbitingObj);
                }
                else
                {
                    orbitingObj = new OrbitObject(orbitingName, orbitedObj);
                    AddObject(orbitingObj);
                    orbitedObj.AddChild(orbitingObj);
                }
            }
示例#3
0
        public int OrbitTransfersRequired(string start, string end)
        {
            HashSet <OrbitObject> visited = new HashSet <OrbitObject>();

            OrbitObject startOrbitObject = ObjectsInSpace[start].ParentOrbitObject;
            OrbitObject endOrbitObject   = ObjectsInSpace[end].ParentOrbitObject;

            visited.Add(startOrbitObject);

            Queue <Tuple <OrbitObject, int> > objectsToVisit = new Queue <Tuple <OrbitObject, int> >();

            objectsToVisit.Enqueue(new Tuple <OrbitObject, int>(startOrbitObject.ParentOrbitObject, 1));
            startOrbitObject.Moons.ForEach(m => objectsToVisit.Enqueue(new Tuple <OrbitObject, int>(m.ParentOrbitObject, 1)));

            while (objectsToVisit.Count > 0)
            {
                var currentOrbitObjectAndPathLength = objectsToVisit.Dequeue();
                var currentOrbitObject = currentOrbitObjectAndPathLength.Item1;
                var pathLength         = currentOrbitObjectAndPathLength.Item2;

                if (currentOrbitObject == endOrbitObject)
                {
                    return(pathLength);
                }

                visited.Add(currentOrbitObject);

                if (!visited.Contains(currentOrbitObject.ParentOrbitObject) && currentOrbitObject.ParentOrbitObject != null)
                {
                    objectsToVisit.Enqueue(new Tuple <OrbitObject, int>(currentOrbitObject.ParentOrbitObject, pathLength + 1));
                }


                currentOrbitObject.Moons.ForEach(m =>
                {
                    if (!visited.Contains(m))
                    {
                        objectsToVisit.Enqueue(new Tuple <OrbitObject, int>(m, pathLength + 1));
                    }
                });
            }

            throw new Exception("Path from " + start + " to " + end + " not found.");
        }
示例#4
0
 public void AddMoon(OrbitObject o)
 {
     Moons.Add(o);
 }
示例#5
0
 public OrbitObject(string name, OrbitObject parentOrbitObject)
 {
     this.Name = name;
     this.ParentOrbitObject = parentOrbitObject;
     Moons = new List <OrbitObject>();
 }
示例#6
0
 /// <summary>
 /// Add an object to the objects in this map.
 /// </summary>
 /// <param name="obj">The OrbitObject to add</param>
 public void AddObject(OrbitObject obj) => OrbitingObjects.Add(obj);