Example #1
0
 public static Tuple <int, int> GetDifferenceVector(
     SolarGridPoint pFrom,
     SolarGridPoint pTo)
 {
     return(new Tuple <int, int>(
                pTo.X - pFrom.X,
                pTo.Y - pFrom.Y));
 }
Example #2
0
 /// <summary>
 /// Get the point lying at the end of the <paramref name="rayVector"/>
 /// extending from <paramref name="centralPoint"/>.
 /// </summary>
 /// <param name="rayVector"></param>
 /// <returns></returns>
 public static SolarGridPoint GetPointAtRayVector(
     SolarGridPoint centralPoint,
     Tuple <int, int> rayVector)
 {
     return(new SolarGridPoint(
                centralPoint.X + rayVector.Item1,
                centralPoint.Y + rayVector.Item2));
 }
        /// <summary>
        /// Given a <paramref name="center"/> point and a
        /// <paramref name="jumpVector"/>, returns the point reached by moving
        /// from the <paramref name="center"/> along
        /// <paramref name="jumpStep"/> multiples of the
        /// <paramref name="jumpVector"/>.
        /// </summary>
        /// <param name="center"></param>
        /// <param name="jumpVector"></param>
        /// <param name="jumpNumber"></param>
        /// <returns></returns>
        public static SolarGridPoint GetJumpPoint(
            SolarGridPoint center,
            Tuple <int, int> jumpVector,
            int jumpStep)
        {
            var displacement = MultiplyVector(jumpVector, jumpStep);
            var resultPoint  = SolarGridPoint.GetPointAtRayVector(
                center, displacement);

            return(resultPoint);
        }
Example #4
0
        public bool GetIsNthBoxFromPointPartiallyWithinMap(SolarGridPoint point, int N)
        {
            var  left               = point.X - N;
            var  right              = point.X + N;
            var  top                = point.Y - N;
            var  bottom             = point.Y + N;
            bool isCompletelyOffMap =
                left < 0 &&
                right >= _width &&
                top < 0 &&
                bottom >= _height;

            return(!isCompletelyOffMap);
        }
Example #5
0
 public SolarObject(int x, int y, SolarObjectType type)
 {
     _gridPoint = new SolarGridPoint(x, y);
     _type      = type;
 }
Example #6
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]);
        }
Example #7
0
 public bool GetIsCoordinateInGrid(SolarGridPoint point)
 {
     return(GetIsCoordinateInGrid(point.X, point.Y));
 }
Example #8
0
        public IList <SolarObject> GetSolarObjectsInNthBoxFromPoint(SolarGridPoint point, int N)
        {
            var result = new List <SolarObject>();

            if (N <= 0)
            {
                return(result);
            }

            // Left side
            var x = point.X - N;
            int y;

            if (x >= 0)
            {
                for (y = point.Y - N; y <= point.Y + N; y++)
                {
                    var coordinate = new SolarGridPoint(x, y);
                    if (_solarObjectDictionary.ContainsKey(coordinate))
                    {
                        result.Add(_solarObjectDictionary[coordinate]);
                    }
                }
            }

            // Bottom side
            y = point.Y + N;
            if (y < _height)
            {
                for (x = point.X - N + 1; x <= point.X + N; x++)
                {
                    var coordinate = new SolarGridPoint(x, y);
                    if (_solarObjectDictionary.ContainsKey(coordinate))
                    {
                        result.Add(_solarObjectDictionary[coordinate]);
                    }
                }
            }

            // Right side
            x = point.X + N;
            if (x < _width)
            {
                for (y = point.Y + N - 1; y >= point.Y - N; y--)
                {
                    var coordinate = new SolarGridPoint(x, y);
                    if (_solarObjectDictionary.ContainsKey(coordinate))
                    {
                        result.Add(_solarObjectDictionary[coordinate]);
                    }
                }
            }

            // Top side
            y = point.Y - N;
            if (y >= 0)
            {
                for (x = point.X + N - 1; x >= point.X - N + 1; x--)
                {
                    var coordinate = new SolarGridPoint(x, y);
                    if (_solarObjectDictionary.ContainsKey(coordinate))
                    {
                        result.Add(_solarObjectDictionary[coordinate]);
                    }
                }
            }

            return(result);
        }
Example #9
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);
        }