public override bool Equals(object obj) { if (this == obj) { return(true); } Day20GridState that = (Day20GridState)obj; return(this.Point.Equals(that.Point) && this.Level == that.Level); }
private void Visit( Queue <Day20GridState> q, HashSet <Day20GridState> visited, Day20GridState state, int xDelta, int yDelta) { Day20GridState newState = null; int newX = state.Point.X + xDelta; int newY = state.Point.Y + yDelta; var p = new Point(newX, newY); if (!grid.ContainsKey(p)) { // not in the grid, can't move here newState = null; } else { char c = grid[p]; if (c == '.') { // movable space newState = new Day20GridState { FromState = state, Steps = state.Steps + 1, Point = new Point(newX, newY), Level = state.Level }; } else { // hit a wall newState = null; } } if (newState != null) { if (visited.Add(newState)) { q.Enqueue(newState); } } }
private int GetDistanceBfs(Day20GridState start, bool useLevels) { Queue <Day20GridState> q = new Queue <Day20GridState>(); HashSet <Day20GridState> visited = new HashSet <Day20GridState>(); q.Enqueue(start); visited.Add(start); while (q.Any()) { Day20GridState state = q.Dequeue(); var thisPortal = portals.FirstOrDefault(p => p.OutputLocation.Equals(state.Point)); string portalName = (thisPortal == null ? null : thisPortal.Name); // we have reached a portal if (portalName != null) { if (state.Level == 0 && portalName == "ZZ") { // this is the exit to the maze return(state.Steps); } // get portals with this name -- there will be two // unless it's AA. If it's one of the others, we // need to queue up a location that is the other // portal var allPortals = portals.Where(p => p.Name.Equals(portalName)); foreach (var p in allPortals) { // if it's not the one we're already on if (!p.OutputLocation.Equals(state.Point)) { int newLevel = 0; if (useLevels) { newLevel = state.Level + CalculateLevel(state.Point); } if (!useLevels || (useLevels && newLevel >= 0)) { // teleport! Day20GridState newState = new Day20GridState { Point = p.OutputLocation, Steps = state.Steps + 1, FromState = state, Level = newLevel }; if (visited.Add(newState)) { q.Enqueue(newState); } } } } } Visit(q, visited, state, -1, 0); Visit(q, visited, state, 1, 0); Visit(q, visited, state, 0, -1); Visit(q, visited, state, 0, 1); } throw new InvalidOperationException(); }