public IEnumerable <Island> Parse(IEnumerable <int> input) { var islands = new List <Island>(); var island = new Island(); foreach (var height in input) { var islandCell = new IslandCell(height); if (CellIsLowerSeaLevel(islandCell)) { if (!IslandIsUnderWater(island)) { islands.Add(island); } island = new Island(); continue; } island.AddCell(islandCell); } islands.Add(island); return(islands); }
public int Execute(IEnumerable <Island> input) { var volume = 0; foreach (var island in input) { var emptyIslandCell = new IslandCell(height: 0); IslandCell currentCell = island.IslandCells.FirstOrDefault() ?? emptyIslandCell; while (currentCell != emptyIslandCell) { var pool = GetPool(island, currentCell); var poolVolume = GetPoolVolume(pool); volume += poolVolume; currentCell = pool.LastOrDefault() ?? emptyIslandCell; } } return(volume); }
private int GetPoolVolume(List <IslandCell> pool) { var poolVolume = 0; var emptyCell = new IslandCell(height: 0); var leftEdge = pool.FirstOrDefault() ?? emptyCell; var rightEdge = pool.LastOrDefault() ?? emptyCell; var minHeightEdge = Math.Min(leftEdge.Height, rightEdge.Height); foreach (var currentCell in pool) { if (currentCell == leftEdge || currentCell == rightEdge) { continue; } var currentVolume = minHeightEdge - currentCell.Height; poolVolume += currentVolume; } return(poolVolume); }
private List <IslandCell> GetPool(Island island, IslandCell startCell) { var islandCells = GetCutIslandsCellsByStartCell(island.IslandCells, startCell); var previewCell = islandCells.FirstOrDefault() ?? new IslandCell(height: 0); var pool = new HashSet <IslandCell>(); var leftPoolEdgeFound = false; var rightPoolEdgeFound = false; foreach (var currentCell in islandCells) { if (rightPoolEdgeFound) { break; } if (leftPoolEdgeFound && previewCell.Height < currentCell.Height) { rightPoolEdgeFound = true; pool.Add(previewCell); pool.Add(currentCell); } if (!leftPoolEdgeFound && previewCell.Height > currentCell.Height) { leftPoolEdgeFound = true; pool.Add(previewCell); pool.Add(currentCell); } if (leftPoolEdgeFound) { pool.Add(currentCell); } previewCell = currentCell; } return(rightPoolEdgeFound && leftPoolEdgeFound?pool.ToList() : new List <IslandCell>()); }
private bool CellIsLowerSeaLevel(IslandCell islandCell) { return(islandCell.Height == 0); }
private List <IslandCell> GetCutIslandsCellsByStartCell(List <IslandCell> islandCells, IslandCell startCell) { var startCellIndex = islandCells.IndexOf(startCell); if (startCellIndex > -1) { islandCells = islandCells.ToList(); islandCells.RemoveRange(index: 0, count: startCellIndex); } else { islandCells = new List <IslandCell>(); } return(islandCells); }