public override void PartTwo(IInput input, IOutput output) { var map = input.As2DPoints() .ToImmutableDictionary(k => k.Point, v => v.Character - '0'); var validPoints = map .Where(kvp => kvp.Value != 9) .Select(kvp => kvp.Key) .ToHashSet(); var basins = new List <HashSet <Point2d> >(); while (validPoints.Count > 0) { var current = validPoints.First(); var basin = FindBasinContainingPoint(current, map); basins.Add(basin); validPoints.ExceptWith(basin); } var sizes = basins .OrderByDescending(basin => basin.Count) .Take(3) .Aggregate(1, (seed, set) => seed * set.Count); output.WriteProperty("Largest Basins Multiplied", sizes);
public override void PartOne(IInput input, IOutput output) { var map = input.As2DPoints() .ToImmutableDictionary(k => k.Point, v => v.Character - '0'); var lowPoints = new HashSet <Point2d>(); foreach (var(point, height) in map) { var neighbours = PointHelpers .GetDirectNeighbours(point); var lowest = neighbours // Go through all possible neighbours .Select(n => map.TryGetValue(n, out var neighbourHeight) ? neighbourHeight : (int?)null) // Get their height or null for missing. .Where(n => n is not null) .All(neighbourHeight => height < neighbourHeight); if (lowest) { lowPoints.Add(point); } } var score = lowPoints .Sum(point => 1 + map[point]); output.WriteProperty("Risk Level", score); }
public static Game Parse(this IInput input, uint elfAttackDamage = 3) { var map = ImmutableDictionary.CreateBuilder <Point2d, CellType>(); var entities = ImmutableArray.CreateBuilder <Entity>(); var points = input.As2DPoints(); foreach (var(point, c) in points) { map[point] = c switch { '#' => CellType.Wall, '.' or 'G' or 'E' => CellType.OpenSpace, _ => throw new NotImplementedException(), }; var entity = c switch { 'G' => new Entity(EntityType.Goblin, point), 'E' => new Entity(EntityType.Elf, point, AttackDamage: elfAttackDamage), _ => null }; if (entity is not null) { entities.Add(entity); } } return(new Game( map.ToImmutable(), entities.ToImmutable())); } }
public static ImmutableDictionary <Point2d, Cell> Parse(this IInput input) { var builder = ImmutableDictionary.CreateBuilder <Point2d, Cell>(); foreach (var(point, c) in input.As2DPoints()) { builder.Add(point, c switch { '#' => Cell.Wall, '.' => Cell.Empty, _ when char.IsDigit(c) => new PointOfInterest(int.Parse($"{c}")), _ => throw new InvalidOperationException("Unable to find cell type"), });
public override void PartOne(IInput input, IOutput output) { var map = input .As2DPoints() .Where(c => c.Character is not ' ') .ToImmutableDictionary(k => k.Point, v => v.Character); var area = Area2d.Create(map.Keys); var(point, character) = map .Where(k => k.Key.X == 0 || k.Key.Y == 0) .Where(v => v.Value is '-' or '|') .Single(); var visited = new HashSet <Point2d> { point }; var direction = StartingDirection(area, point, character); var letters = new List <char>(); while (true) { var @char = map[point]; if (@char is '+') { (direction, _) = Direction.CardinalDirections .Select(dir => (Direction: dir, Point: point + dir)) .Where(n => map.ContainsKey(n.Point) && visited.Contains(n.Point) is false) .Single(); } else if (char.IsLetter(@char)) { letters.Add(@char); } if (map.ContainsKey(point + direction) is false) { break; } point += direction; visited.Add(point); } output.WriteProperty("Final letters", string.Join("", letters)); }
public static ImmutableDictionary <Point2d, uint> ParseOctopi(this IInput input) { return(input.As2DPoints() .ToImmutableDictionary(k => k.Point, v => (uint)v.Character - '0')); }
public static ImmutableDictionary <Point2d, int> ParseMap(this IInput input) => input.As2DPoints() .ToImmutableDictionary(k => k.Point, v => v.Character - '0');