示例#1
0
        public IEnumerable <Node> Neigbours(Node node)
        {
            var(point, currentTool) = node;

            var currentRegion     = _factory.Calculate(point);
            var currentValidTools = GetValidTools(currentRegion.CellType);

            foreach (var otherTool in Tools.Where(t => t != node.Tool && currentValidTools.Contains(t)))
            {
                yield return(new Node(node.Position, otherTool));
            }

            foreach (var neighbour in PointHelpers.GetDirectNeighbours(node.Position))
            {
                if (neighbour.X < 0 || neighbour.Y < 0)
                {
                    continue;
                }

                var regionDetails = _factory.Calculate(neighbour);

                var validTools = GetValidTools(regionDetails.CellType);

                if (validTools.Contains(currentTool))
                {
                    yield return(new Node(neighbour, node.Tool));
                }
            }
        }
示例#2
0
    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);
    }
示例#3
0
 public IEnumerable <Point2d> Neigbours(Point2d node)
 {
     return(PointHelpers.GetDirectNeighbours(node)
            .Where(point => point.X >= 0 && point.Y >= 0)
            .Where(point => _office.ContainsKey(point))
            .Where(point => _office[point] is not CellType.Wall));
 }
示例#4
0
        static HashSet <Point2d> FindBasinContainingPoint(Point2d source, IReadOnlyDictionary <Point2d, int> map)
        {
            var currentFrontier = new List <Point2d>();
            var nextFrontier    = new List <Point2d>();

            currentFrontier.Add(source);
            var visited = new HashSet <Point2d>
            {
                source
            };

            while (currentFrontier.Count > 0)
            {
                foreach (var current in currentFrontier)
                {
                    foreach (var next in PointHelpers.GetDirectNeighbours(current))
                    {
                        if (map.TryGetValue(next, out var nextHeight) && nextHeight != 9)
                        {
                            if (visited.Add(next) is true)
                            {
                                nextFrontier.Add(next);
                            }
                        }
                    }
                }

                (currentFrontier, nextFrontier) = (nextFrontier, currentFrontier);
                nextFrontier.Clear();
            }

            return(visited);
        }
示例#5
0
        static ImmutableArray <Point2d> FindPath(
            ImmutableDictionary <Point2d, Cell> map,
            Func <State, bool> goalReached,
            Point2d start)
        {
            var startState = new State(start, ImmutableSortedSet.Create(0));
            var frontier   = new PriorityQueue <State, float>();

            frontier.Enqueue(startState, 0);

            var cameFrom = new Dictionary <State, State>()
            {
                [startState] = startState
            };

            var costSoFar = new Dictionary <State, float>()
            {
                [startState] = 0
            };

            State?finishedState = null;

            while (frontier.TryDequeue(out var current, out _))
            {
                if (goalReached(current))
                {
                    finishedState = current;
                    break;
                }

                foreach (var next in PointHelpers.GetDirectNeighbours(current.Position))
                {
                    if (map.TryGetValue(next, out var nextCell) is false || nextCell.Type is CellType.Wall)
                    {
                        continue;
                    }

                    var newVisited = nextCell is PointOfInterest poi
                        ? current.Visited.Add(poi.Number)
                        : current.Visited;

                    var nextState = new State(next, newVisited);

                    var newCost = costSoFar[current] + 1;
                    if (costSoFar.TryGetValue(nextState, out var nextCost) is false || newCost < nextCost)
                    {
                        costSoFar[nextState] = newCost;
                        frontier.Enqueue(nextState, newCost);
                        cameFrom[nextState] = current;
                    }
                }
            }

            if (finishedState is null)
            {
                return(ImmutableArray <Point2d> .Empty);
            }

            return(Algorithms.ReconstructPath(startState, finishedState, cameFrom)
                   .Select(state => state.Position)
                   .ToImmutableArray());
        }