private IEnumerable <SeatNeighborhood> GetImmediateSeatNeighborhoods(SeatsMap sm) { List <SeatNeighborhood> neighborhoods = new List <SeatNeighborhood>(); foreach (Tuple <int, int> seat in sm.Seats) { // Unrolling the cases for all eight directions. SeatNeighborhood sn = new SeatNeighborhood(seat); Tuple <int, int> candidate = Tuple.Create(seat.Item1 - 1, seat.Item2 - 1); if (sm.ContainsKey(candidate)) { sn.SetNeighbor(Direction.TopLeft, candidate); } candidate = Tuple.Create(seat.Item1 - 1, seat.Item2); if (sm.ContainsKey(candidate)) { sn.SetNeighbor(Direction.Top, candidate); } candidate = Tuple.Create(seat.Item1 - 1, seat.Item2 + 1); if (sm.ContainsKey(candidate)) { sn.SetNeighbor(Direction.TopRight, candidate); } candidate = Tuple.Create(seat.Item1, seat.Item2 + 1); if (sm.ContainsKey(candidate)) { sn.SetNeighbor(Direction.Right, candidate); } candidate = Tuple.Create(seat.Item1 + 1, seat.Item2 + 1); if (sm.ContainsKey(candidate)) { sn.SetNeighbor(Direction.BottomRight, candidate); } candidate = Tuple.Create(seat.Item1 + 1, seat.Item2); if (sm.ContainsKey(candidate)) { sn.SetNeighbor(Direction.Bottom, candidate); } candidate = Tuple.Create(seat.Item1 + 1, seat.Item2 - 1); if (sm.ContainsKey(candidate)) { sn.SetNeighbor(Direction.BottomLeft, candidate); } candidate = Tuple.Create(seat.Item1, seat.Item2 - 1); if (sm.ContainsKey(candidate)) { sn.SetNeighbor(Direction.Left, candidate); } yield return(sn); } }
private void Stabilize (SeatsMap sm , Func <SeatsMap, IEnumerable <SeatNeighborhood> > getNeighborhoods , int maxUsedNeighbors) { bool iterate = true; List <SeatNeighborhood> neighborhoods = getNeighborhoods(sm).ToList(); while (iterate) { var modifications = GetModifications(sm, neighborhoods, maxUsedNeighbors).ToList(); iterate = modifications.Any(); foreach (var tuple in modifications) { sm[tuple.Item1] = tuple.Item2; } } }
private IEnumerable <Tuple <Tuple <int, int>, char> > GetModifications (SeatsMap sm , IEnumerable <SeatNeighborhood> neighborhoods , int maxUsedNeighbors) { foreach (SeatNeighborhood sn in neighborhoods) { switch (sm[sn.Seat]) { case FreeSeat when sn.Neighbors.All(seat => sm[seat] == FreeSeat): yield return(Tuple.Create(sn.Seat, UsedSeat)); break; case UsedSeat when sn.Neighbors.Count(seat => sm[seat] == UsedSeat) >= maxUsedNeighbors: yield return(Tuple.Create(sn.Seat, FreeSeat)); break; } } }
private SeatsMap GetSeatsMap(IEnumerable <string> input) { SeatsMap sm = new SeatsMap(); int row = 0; foreach (var line in input) { int col = 0; foreach (var c in line) { if (c == FreeSeat) { sm[row, col] = c; } col++; } row++; } return(sm); }
private IEnumerable <SeatNeighborhood> GetClosestSeatNeighborhoods(SeatsMap sm) { List <SeatNeighborhood> neighborhoods = new List <SeatNeighborhood>(); foreach (Tuple <int, int> seat in sm.Seats) { SeatNeighborhood sn = new SeatNeighborhood(seat); foreach (SeatNeighborhood neighborhood in neighborhoods) { if (TryGetDirection(neighborhood.Seat, seat, out var direction)) { Direction opposite = GetOppositeDirection(direction); Tuple <int, int> neighbor = neighborhood.GetNeighbor(direction); if (neighbor is Tuple <int, int> ) { int neighborDist = GetManhattanDistance(neighbor, neighborhood.Seat); int seatDist = GetManhattanDistance(seat, neighborhood.Seat); if (seatDist < neighborDist) { neighborhood.SetNeighbor(direction, seat); sn.SetNeighbor(opposite, neighborhood.Seat); } } else { neighborhood.SetNeighbor(direction, seat); sn.SetNeighbor(opposite, neighborhood.Seat); } } } neighborhoods.Add(sn); } return(neighborhoods); }