Ejemplo n.º 1
0
        // Assumes the station starts rotating clockwise from vertical
        public SolarObject GetNthAsteroidVaporized(
            SolarGridPoint centerPoint,
            int n)
        {
            if (n < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(n));
            }
            // Initialize the set of objects remaining
            var pointsRemaining = _solarObjectDictionary
                                  .Select(kvp => kvp.Key)
                                  .ToHashSet();

            if (pointsRemaining.Contains(centerPoint))
            {
                pointsRemaining.Remove(centerPoint);
            }

            // Initialize the ordered list of objects vaporized
            var objectsVaporized = new List <SolarObject>();

            // On each rotation, get the list of objects vaporized, ordered
            // clockwise from the starting angle
            int currentRotation     = 1;
            var startingLaserVector = new Tuple <Radical, Radical>(0, -1);

            while (pointsRemaining.Count > 0)
            {
                // Get the list of objects seen (and therefore vaporized)
                // on this rotation
                var objectsVaporizedOnRotation =
                    GetObjectsVisibleFromPoint(centerPoint, pointsRemaining);

                // Order by clockwise angle
                var objectsVaporizedOnRotationOrdered = objectsVaporizedOnRotation
                                                        .Select(o => new Tuple <double, SolarObject>(
                                                                    VectorHelper.GetClockwiseAngleBetweenVectors(
                                                                        startingLaserVector,
                                                                        SolarGridPoint.GetDifferenceVector(centerPoint, o.GridPoint).ToRadicalVector()),
                                                                    o))
                                                        .OrderBy(o => o.Item1)
                                                        .ToList();

                // Remove the objects vaporized from the remaining list
                foreach (var vaporizedObject in objectsVaporizedOnRotation)
                {
                    if (pointsRemaining.Contains(vaporizedObject.GridPoint))
                    {
                        pointsRemaining.Remove(vaporizedObject.GridPoint);
                    }
                }

                // Add ordered list of objects to
                objectsVaporized.AddRange(objectsVaporizedOnRotationOrdered.Select(o => o.Item2));

                currentRotation++;
            }

            // Get the nth item
            if (n - 1 >= objectsVaporized.Count)
            {
                return(null);
            }
            return(objectsVaporized[n - 1]);
        }
Ejemplo n.º 2
0
        public IList <SolarObject> GetObjectsVisibleFromPoint(
            SolarGridPoint point,
            HashSet <SolarGridPoint> pointsToCheck)
        {
            // Define a "jump vector" as a displacement from the given
            // central point to another point.
            // 1) For each integer n starting with 1, find all jump vectors where
            //    |x| + |y| = n.
            // 2a) For each jump vector for a given n, move outwards from the
            //     central point in multiples of the given jump vector.
            // 2b) If a point is encountered containing an object that hasn't
            //     been seen before, then mark that object as seen. Afterwards,
            //     mark any subsequent objects encountered as blocked.
            IList <SolarObject> objectsSeen = new List <SolarObject>();
            var pointsChecked = new HashSet <SolarGridPoint>();
            var displacementVectorsChecked = new HashSet <Tuple <int, int> >();
            var numberToCheck = pointsToCheck.Count;
            int jumpNumber    = 1;

            while (pointsChecked.Count < numberToCheck)
            {
                // Get all jump vectors for this n
                var jumpVectors = VectorHelper.GetJumpVectors(jumpNumber);

                foreach (var jumpVector in jumpVectors)
                {
                    int jumpStep           = 1;
                    var displacementVector = VectorHelper.MultiplyVector(jumpVector, jumpStep);
                    if (displacementVectorsChecked.Contains(displacementVector))
                    {
                        continue;
                    }
                    displacementVectorsChecked.Add(displacementVector);
                    var  currentPoint = SolarGridPoint.GetPointAtRayVector(point, displacementVector);
                    bool encounteredObjectAlongRay = false;
                    while (GetIsCoordinateInGrid(currentPoint))
                    {
                        if (pointsChecked.Contains(currentPoint))
                        {
                            continue;
                        }

                        // Check if the point contains an object
                        if (pointsToCheck.Contains(currentPoint))
                        {
                            if (!encounteredObjectAlongRay)
                            {
                                objectsSeen.Add(_solarObjectDictionary[currentPoint]);
                                encounteredObjectAlongRay = true;
                            }
                            pointsChecked.Add(currentPoint);
                        }

                        jumpStep++;
                        displacementVector = VectorHelper.MultiplyVector(jumpVector, jumpStep);
                        displacementVectorsChecked.Add(displacementVector);
                        currentPoint = SolarGridPoint.GetPointAtRayVector(point, displacementVector);
                    }
                }

                jumpNumber++;
            }
            return(objectsSeen);
        }