示例#1
0
        private Dictionary <Point, int> Solve2_BruteForce(int maxSquareSize, IEnumerable <Point> grid, Dictionary <Point, int> pointPowerLevel)
        {
            Dictionary <Point, Tuple <int, int> > pointSquareTotalPowerSquareSize = new Dictionary <Point, Tuple <int, int> >();

            foreach (int squareSize in RangeHelpers.GenerateRange(1, maxSquareSize))
            {
                Dictionary <Point, int> pointSquareTotalPower = new Dictionary <Point, int>();

                EvaluateGridPowerLevel(grid, ref pointPowerLevel, ref pointSquareTotalPower, squareSize);

                foreach (var pair in pointSquareTotalPower)
                {
                    if (pointSquareTotalPowerSquareSize.TryGetValue(pair.Key, out Tuple <int, int> value))
                    {
                        if (value.Item1 < pair.Value)
                        {
                            pointSquareTotalPowerSquareSize[pair.Key] = Tuple.Create(pair.Value, squareSize);
                        }
                    }
                    else
                    {
                        pointSquareTotalPowerSquareSize[pair.Key] = Tuple.Create(pair.Value, squareSize);
                    }
                }
            }

            var pairWithMaxPower = pointSquareTotalPowerSquareSize.OrderByDescending(pair => pair.Value.Item1).First();

            Console.Write($"\nDay 11, part 2: {pairWithMaxPower.Key}, {pairWithMaxPower.Value.Item2}");
            return(pointPowerLevel);
        }
示例#2
0
        private void ComputeRange()
        {
            // 14.35 Range
            // http://tools.ietf.org/html/draft-ietf-httpbis-p5-range-24

            // A server MUST ignore a Range header field received with a request method other
            // than GET.
            if (!_isGet)
            {
                return;
            }

            string rangeHeader = _request.Headers.Get(Constants.Range);
            IList <Tuple <long?, long?> > ranges;

            if (!RangeHelpers.TryParseRanges(rangeHeader, out ranges))
            {
                return;
            }

            if (ranges.Count > 1)
            {
                // multiple range headers not yet supported
                return;
            }

            // 14.27 If-Range
            string ifRangeHeader = _request.Headers.Get(Constants.IfRange);

            if (!string.IsNullOrWhiteSpace(ifRangeHeader))
            {
                // If the validator given in the If-Range header field matches the
                // current validator for the selected representation of the target
                // resource, then the server SHOULD process the Range header field as
                // requested.  If the validator does not match, the server MUST ignore
                // the Range header field.
                DateTime ifRangeLastModified;
                bool     ignoreRangeHeader = false;
                if (Helpers.TryParseHttpDate(ifRangeHeader, out ifRangeLastModified))
                {
                    if (_lastModified > ifRangeLastModified)
                    {
                        ignoreRangeHeader = true;
                    }
                }
                else
                {
                    if (!_etagQuoted.Equals(ifRangeHeader))
                    {
                        ignoreRangeHeader = true;
                    }
                }
                if (ignoreRangeHeader)
                {
                    return;
                }
            }

            _ranges = RangeHelpers.NormalizeRanges(ranges, _length);
        }
示例#3
0
        private void EvaluateGridPowerLevel(IEnumerable <Point> grid, ref Dictionary <Point, int> pointPowerLevel, ref Dictionary <Point, int> pointSquareTotalPower, int squareSize)
        {
            Console.WriteLine($"Evaluating power level for squares sized {squareSize}");

            foreach (Point point in grid)
            {
                if (point.X + squareSize > 300 ||
                    point.Y + squareSize > 300)
                {
                    continue;
                }

                IEnumerable <Point> points = Point.GeneratePointRangeIteratingOverXFirst(
                    RangeHelpers.GenerateRange(point.X, point.X + (squareSize - 1)),
                    RangeHelpers.GenerateRange(point.Y, point.Y + (squareSize - 1)));

                int totalPower = 0;
                foreach (Point p in points)
                {
                    if (pointPowerLevel.TryGetValue(p, out int pPower))
                    {
                        totalPower += pPower;
                    }
                    else
                    {
                        pPower = CalculatePowerLevel(p);
                        pointPowerLevel.Add(p, pPower);
                        totalPower += pPower;
                    }
                }
                pointSquareTotalPower.Add(point, totalPower);
            }
        }
示例#4
0
        private HashSet <Point> ExtractCandidateLocations(ICollection <Point> allPoints)
        {
            List <Point> edgePoints = ExtractEdgePoints(allPoints);

            int minX = edgePoints.Min(p => p.X);
            int minY = edgePoints.Min(p => p.Y);
            int maxX = edgePoints.Max(p => p.X);
            int maxY = edgePoints.Max(p => p.Y);

            var xRange = RangeHelpers.GenerateRange(minValue: maxX - _distanceConstraint, maxValue: minX + _distanceConstraint);
            var yRange = RangeHelpers.GenerateRange(minValue: maxY - _distanceConstraint, maxValue: minY + _distanceConstraint);

            // 10_000 x 10_0000, not being able to invoke GeneratePointRange yet

            // Providing all points are in minX, but one that is in maxX:
            ulong      extraMinYDistanceToConsider = (ulong)(maxY - minY); // 160_000 -> ~151_000
            List <int> curatedXRange = new List <int>();

            foreach (int x in xRange)
            {
                ulong xCounter = 0;
                foreach (int pX in allPoints.Select(p => p.X))
                {
                    xCounter += (ulong)Math.Abs(x - pX);
                    if (xCounter > _distanceConstraint)
                    {
                        break;
                    }
                }

                if (xCounter + extraMinYDistanceToConsider <= _distanceConstraint)
                {
                    curatedXRange.Add(x);
                }
            }

            // Providing all points are in minY, but one that is in maxY:
            ulong      extraMinXDistanceToConsider = (ulong)(maxX - minX); // 160_000 -> ~151_000
            List <int> curatedYRange = new List <int>();

            foreach (int y in yRange)
            {
                ulong yCounter = 0;
                foreach (int pY in allPoints.Select(p => p.Y))
                {
                    yCounter += (ulong)Math.Abs(y - pY);
                    if (yCounter > _distanceConstraint)
                    {
                        break;
                    }
                }

                if (yCounter + extraMinXDistanceToConsider <= _distanceConstraint)
                {
                    curatedYRange.Add(y);
                }
            }

            return(Point.GeneratePointRangeIteratingOverYFirst(curatedXRange, curatedYRange).ToHashSet());
        }
示例#5
0
            private void ComputeRange()
            {
                // 14.35 Range
                // http://tools.ietf.org/html/draft-ietf-httpbis-p5-range-24

                // A server MUST ignore a Range header field received with a request method other
                // than GET.
                if (!_isGet)
                {
                    return;
                }

                var rangeHeader = _requestHeaders.Range;

                if (rangeHeader == null)
                {
                    return;
                }

                if (rangeHeader.Ranges.Count > 1)
                {
                    // The spec allows for multiple ranges but we choose not to support them because the client may request
                    // very strange ranges (e.g. each byte separately, overlapping ranges, etc.) that could negatively
                    // impact the server. Ignore the header and serve the response normally.
                    LoggerExtensions.LogMultipleFileRanges(_logger, rangeHeader.ToString());
                    return;
                }

                // 14.27 If-Range
                var ifRangeHeader = _requestHeaders.IfRange;

                if (ifRangeHeader != null)
                {
                    // If the validator given in the If-Range header field matches the
                    // current validator for the selected representation of the target
                    // resource, then the server SHOULD process the Range header field as
                    // requested.  If the validator does not match, the server MUST ignore
                    // the Range header field.
                    bool ignoreRangeHeader = false;
                    if (ifRangeHeader.LastModified.HasValue)
                    {
                        if (_lastModified > ifRangeHeader.LastModified)
                        {
                            ignoreRangeHeader = true;
                        }
                    }
                    else if (ifRangeHeader.EntityTag != null && !_etag.Equals(ifRangeHeader.EntityTag))
                    {
                        ignoreRangeHeader = true;
                    }
                    if (ignoreRangeHeader)
                    {
                        return;
                    }
                }

                _ranges = RangeHelpers.NormalizeRanges(rangeHeader.Ranges, _length);
            }
示例#6
0
        private HashSet <Point> ExtractAreaOfInterest(ICollection <Point> edgePoints)
        {
            int minX = edgePoints.Min(p => p.X);
            int minY = edgePoints.Min(p => p.Y);
            int maxX = edgePoints.Max(p => p.X);
            int maxY = edgePoints.Max(p => p.Y);

            var xRange = RangeHelpers.GenerateRange(minValue: minX, maxValue: maxX);
            var yRange = RangeHelpers.GenerateRange(minValue: minY, maxValue: maxY);

            return(Point.GeneratePointRangeIteratingOverYFirst(xRange, yRange).ToHashSet());
        }
示例#7
0
        private bool PrintStarsPosition(HashSet <Star> stars)
        {
            Point downLeft = new Point(stars.Min(star => star.X), stars.Min(star => star.Y));
            Point upRight  = new Point(stars.Max(star => star.X), stars.Max(star => star.Y));

            if (Math.Abs(downLeft.X - upRight.X) < 150 &&
                Math.Abs(downLeft.Y - upRight.Y) < 150)
            {
                Console.Clear();

                var xRange = RangeHelpers.GenerateRange(minValue: downLeft.X, maxValue: upRight.X);
                var yRange = RangeHelpers.GenerateRange(minValue: downLeft.Y, maxValue: upRight.Y);

                var points = Point.GeneratePointRangeIteratingOverXFirst(xRange, yRange);
                int y0     = points.First().Y;

                foreach (Point point in points)
                {
                    if (point.Y != y0)
                    {
                        y0 = point.Y;
                        Console.WriteLine();
                    }

                    Console.Write(
                        stars.Any(star => star.X == point.X && star.Y == point.Y)
                        ? "X"
                        : "-");
                }

                Console.WriteLine();

                // Automatic end
                if (Math.Abs(downLeft.X - upRight.X) == 61 &&
                    Math.Abs(downLeft.Y - upRight.Y) == 9)
                {
                    return(true);
                }

                // Manual end
                //string end = Console.ReadLine();
                //return end.ToUpperInvariant() == "Y";
            }

            return(false);
        }
示例#8
0
        private IEnumerable <Point> GenerateGrid()
        {
            var rangeXAndY = RangeHelpers.GenerateRange(minValue: 1, maxValue: 300);

            return(Point.GeneratePointRangeIteratingOverXFirst(rangeXAndY, rangeXAndY));
        }
示例#9
0
        private void EvaluatePointPowerLevelWithDifferentSquareSizes(Point point, ref Dictionary <Point, int> pointPowerLevel, ref Dictionary <Point, Tuple <int, int> > pointSquareTotalPowerSquareSize)
        {
            Console.WriteLine($"Evaluating point {point}");

            int maxSquareSize           = Math.Min(Math.Abs(300 - point.X), Math.Abs(300 - point.Y));
            IEnumerable <int> sizeRange = RangeHelpers.GenerateRange(1, maxSquareSize);

            Dictionary <int, int> squareSizeValues = new Dictionary <int, int>();

            HashSet <Point> previousSizePoints = new HashSet <Point>();

            foreach (int squareSize in sizeRange)
            {
                Console.WriteLine($"  Evaluating power level for squares sized {squareSize}");

                if (point.X + squareSize > 300 ||
                    point.Y + squareSize > 300)
                {
                    continue;
                }

                IEnumerable <Point> points = Point.GeneratePointRangeIteratingOverXFirst(
                    RangeHelpers.GenerateRange(point.X, point.X + (squareSize - 1)),
                    RangeHelpers.GenerateRange(point.Y, point.Y + (squareSize - 1)));

                int totalPower = 0;
                if (previousSizePoints.Any())
                {
                    var newPoints = points.ToHashSet().Except(previousSizePoints);
                    int newPower  = 0;
                    foreach (Point p in newPoints)
                    {
                        if (pointPowerLevel.TryGetValue(p, out int pPower))
                        {
                            newPower += pPower;
                        }
                        else
                        {
                            pPower = CalculatePowerLevel(p);
                            pointPowerLevel.Add(p, pPower);
                            newPower += pPower;
                        }
                    }

                    //if (newPower < 0)
                    //{
                    //    continue;
                    //}

                    totalPower = squareSizeValues.Last().Value + newPower;
                    previousSizePoints.UnionWith(newPoints.ToHashSet());
                }
                else
                {
                    foreach (Point p in points)
                    {
                        if (pointPowerLevel.TryGetValue(p, out int pPower))
                        {
                            totalPower += pPower;
                        }
                        else
                        {
                            pPower = CalculatePowerLevel(p);
                            pointPowerLevel.Add(p, pPower);
                            totalPower += pPower;
                        }
                    }

                    if (pointSquareTotalPowerSquareSize.TryGetValue(point, out var value))
                    {
                        if (totalPower > value.Item1)
                        {
                            pointSquareTotalPowerSquareSize[point] = Tuple.Create(totalPower, squareSize);
                        }
                    }
                    else
                    {
                        pointSquareTotalPowerSquareSize[point] = Tuple.Create(totalPower, squareSize);
                    }
                    previousSizePoints = points.ToHashSet();
                }
                squareSizeValues.Add(squareSize, totalPower);
            }

            if (squareSizeValues.Any())
            {
                var max = squareSizeValues.OrderByDescending(pair => pair.Value).First();
                pointSquareTotalPowerSquareSize[point] = Tuple.Create(max.Value, max.Key);
            }
        }