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); }
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); }
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); } }
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()); }
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); }
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()); }
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); }
private IEnumerable <Point> GenerateGrid() { var rangeXAndY = RangeHelpers.GenerateRange(minValue: 1, maxValue: 300); return(Point.GeneratePointRangeIteratingOverXFirst(rangeXAndY, rangeXAndY)); }
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); } }