// Find the lowest number of days that will require to update all the serves on the grid. // Where every server with the value of 1 is updated and can update any other server that is above, below, next or previous. // A server that requires an update is represented by 0 value and an updated server is represented by 1 value. // Any server that needs to be updated will take 1 day to update. // sameple grid -- result should be 3 let grid: [[Int]] = [[0, 1, 1, 1], [1, 1, 0, 1], [1, 1, 1, 1], [1, 0, 1, 1], [1, 1, 1, 1]] extension Array where Element == [Int] { func aboveItem(row: Int, rowIndex: Int) -> Int? { if (row == 0) { return nil } let aboveRow: [Int] = self[row-1] if rowIndex < aboveRow.count { return aboveRow[rowIndex] } return nil } func belowItem(row: Int, rowIndex: Int) -> Int? { let rowCount: Int = self.count if row == rowCount-1 { return nil } let belowRow: [Int] = self[row+1] if rowIndex < belowRow.count { return belowRow[rowIndex] } return nil } } extension Array where Element == Int { func previousItem(index: Int) -> Int? { if index == 0 { return nil } if index < self.count { return self[index-1] } return nil } func nextItem(index: Int) -> Int? { let count: Int = self.count if index == count-1 { return nil } if index < count { return self[index+1] } return nil } } extension Optional where Wrapped == Int { var notZeroValue: Bool { if let zero = self { if zero == 1 { return true } } return false } } struct GridLocation: Hashable { var list: Int var index: Int static func == (lhs: GridLocation, rhs: GridLocation) -> Bool { return lhs.list == rhs.list && lhs.index == rhs.index } } func findLowestNumberOfDaysToUpdate(grid: [[Int]]) -> Int { if grid.isEmpty { return 0 } var numberOfDays: Int = 0 var gridLocationSet = Set() // loading all the 0 values and getting their location for (arrayIndex, array) in grid.enumerated() { for (index, value) in array.enumerated() where value == 0 { let location = GridLocation(list: arrayIndex, index: index) if !gridLocationSet.contains(location) { gridLocationSet.insert(location) } } } for location in gridLocationSet { // getting all the possible neightbours let above = grid.aboveItem(row: location.list, rowIndex: location.index) let below = grid.belowItem(row: location.list, rowIndex: location.index) let previous = grid[location.list].previousItem(index: location.index) let next = grid[location.list].nextItem(index: location.index) if above.notZeroValue || below.notZeroValue || previous.notZeroValue || next.notZeroValue { numberOfDays += 1 } else if !above.notZeroValue && !below.notZeroValue && !previous.notZeroValue && !next.notZeroValue { // needs work! numberOfDays += 2 } } return numberOfDays } // printing the result print(findLowestNumberOfDaysToUpdate(grid: grid))