Last active
August 15, 2017 14:59
-
-
Save vukcevich/b0ee809e8d186be22ab3df3fa1416ec3 to your computer and use it in GitHub Desktop.
Swift playground that takes an n x n grid of integers...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| Coding Test -- Envoy: | |
| Write a Swift playground that takes an n x n grid of integers. Each integer can be either 1 or 0. | |
| The playground then outputs an n x n grid where each block indicates the number of 1's around that block, (excluding the block itself) . For Block 0 on row 0, surrounding blocks are (0,1) (1,0) and (1,1). Similary for block (1,1) all the blocks around it are to be counted as surrounding blocks. | |
| Requirements: | |
| Make sure your solution works for any size grid. | |
| Spend an hour and a half coding the logic and another hour cleaning your code (adding comments, cleaning variable and function names). | |
| Optimize your functions to be O(n^2). | |
| Your output lines should not have any trailing or leading whitespaces. | |
| Please use hard coded example input constants below. | |
| Examples: | |
| Input Grid: | |
| let sampleGrid = [[0,1,0], [0,0,0], [1,0,0]] | |
| Console Output: | |
| 1 0 1 | |
| 2 2 1 | |
| 0 1 0 | |
| ///////////////// | |
| Input Grid: | |
| let sampleGrid = [[0,1,0,0], [0,0,0,1], [1,0,0,1],[0,1,0,1]] | |
| Console Output: | |
| 1 0 2 1 | |
| 2 2 3 1 | |
| 1 2 4 2 | |
| 2 1 3 1 | |
| */ | |
| import UIKit | |
| class SampleGrid { | |
| let gridData:[[Int]] | |
| init(data: [[Int]]) { | |
| self.gridData = data | |
| createNewGrid(gridData: self.gridData) | |
| } | |
| func createNewGrid(gridData:[[Int]]) { | |
| var updatedGrid: [[Int]] = [] | |
| for x in 0..<gridData.count { | |
| updatedGrid.append([Int]()) | |
| for y in 0..<gridData[x].count { | |
| let newValue = updateValueForPosition(row: x, col: y, data: gridData, rowLen: gridData.count, colLen: gridData[0].count) | |
| updatedGrid[x].append(newValue) | |
| } | |
| } | |
| print("Output: \(updatedGrid)") | |
| } | |
| func updateValueForPosition(row: Int, col: Int, data: [[Int]], rowLen: Int, colLen: Int) -> Int { | |
| let rowBefore = data.index(before: row) | |
| let rowAfter = data.index(after: row) | |
| let colBefore = data[row].index(before: col) | |
| let colAfter = data[row].index(after: col) | |
| var totalValue = 0 | |
| if (rowBefore == -1) { | |
| //Handle first row - only | |
| //same for First Row - all columns | |
| if( data[rowAfter][col] == 1 ) { | |
| totalValue += 1 | |
| } | |
| if (colBefore == -1) { | |
| //First Row - handle first col | |
| if( data[row][colAfter] == 1 ) { | |
| totalValue += 1 | |
| } | |
| if( data[rowAfter][colAfter] == 1 ) { | |
| totalValue += 1 | |
| } | |
| } else if (colAfter == colLen) { | |
| //First Row - handle last col | |
| if(data[row][colBefore] == 1 ) { | |
| totalValue += 1 | |
| } | |
| if(data[rowAfter][colBefore] == 1 ) { | |
| totalValue += 1 | |
| } | |
| } else { | |
| //For larger NxN grids - First Row | |
| if(data[row][colBefore] == 1 ) { | |
| totalValue += 1 | |
| } | |
| if(data[row][colAfter] == 1 ) { | |
| totalValue += 1 | |
| } | |
| if(data[rowAfter][colBefore] == 1 ) { | |
| totalValue += 1 | |
| } | |
| if(data[rowAfter][colAfter] == 1 ) { | |
| totalValue += 1 | |
| } | |
| } | |
| } else if (rowAfter == rowLen) { | |
| //Handle Last Row") | |
| //same for all columns - Last Row | |
| if( data[rowBefore][col] == 1 ) { | |
| totalValue += 1 | |
| } | |
| if (colBefore == -1) { | |
| //Last Row - handle first col") | |
| if( data[row][colAfter] == 1 ) { | |
| totalValue += 1 | |
| } | |
| if( data[rowBefore][colAfter] == 1 ) { | |
| totalValue += 1 | |
| } | |
| } else if (colAfter == colLen) { | |
| //Last Row - handle last col") | |
| if(data[row][colBefore] == 1 ) { | |
| totalValue += 1 | |
| } | |
| if(data[rowBefore][colBefore] == 1 ) { | |
| totalValue += 1 | |
| } | |
| } else { | |
| //For larger NxN Grids - Last Row | |
| if(data[row][colBefore] == 1 ) { | |
| totalValue += 1 | |
| } | |
| if(data[row][colAfter] == 1 ) { | |
| totalValue += 1 | |
| } | |
| if(data[rowBefore][colBefore] == 1 ) { | |
| totalValue += 1 | |
| } | |
| if(data[rowBefore][colAfter] == 1 ) { | |
| totalValue += 1 | |
| } | |
| } | |
| } else { | |
| //Middle Rows --- larger NxN grids - not first row and not last row | |
| //same for all middle rows | |
| if(data[rowBefore][col] == 1 ) { | |
| totalValue += 1 | |
| } | |
| if(data[rowAfter][col] == 1) { | |
| totalValue += 1 | |
| } | |
| if (colBefore == -1) { | |
| //Middle Row - handle first col | |
| //row before | |
| if( data[rowBefore][colAfter] == 1) { | |
| totalValue += 1 | |
| } | |
| //current row | |
| if( data[row][colAfter] == 1 ) { | |
| totalValue += 1 | |
| } | |
| //row after | |
| if (data[rowAfter][colAfter] == 1 ) { | |
| totalValue += 1 | |
| } | |
| } else if (colAfter == colLen) { | |
| //Middle Row - handle last col | |
| //row before | |
| if( data[rowBefore][colBefore] == 1) { | |
| totalValue += 1 | |
| } | |
| //current row | |
| if( data[row][colBefore] == 1 ) { | |
| totalValue += 1 | |
| } | |
| //row after | |
| if (data[rowAfter][colBefore] == 1 ) { | |
| totalValue += 1 | |
| } | |
| } else { | |
| // Middle Row - for larger NxN grids | |
| //row before | |
| if( data[rowBefore][colBefore] == 1) { | |
| totalValue += 1 | |
| } | |
| if( data[rowBefore][colAfter] == 1) { | |
| totalValue += 1 | |
| } | |
| //current row | |
| if( data[row][colBefore] == 1) { | |
| totalValue += 1 | |
| } | |
| if( data[row][colAfter] == 1) { | |
| totalValue += 1 | |
| } | |
| //row after | |
| if( data[rowAfter][colBefore] == 1) { | |
| totalValue += 1 | |
| } | |
| if( data[rowAfter][colAfter] == 1) { | |
| totalValue += 1 | |
| } | |
| } | |
| } | |
| return totalValue | |
| } | |
| } | |
| let sampleGrid = [[0,1,0], [0,0,0], [1,0,0]] | |
| let sampleGrid2 = [[0,1,0,0], [0,0,0,1], [1,0,0,1],[0,1,0,1]] | |
| let sampleGrid3 = [[0,0,0,0,0,0], [0,0,1,0,0,0], [0,0,0,1,0,0], [0,0,1,0,0,0], [0,0,0,0,0,0], [0,0,0,0,1,0]] | |
| /* | |
| import CoreFoundation | |
| class ParkBenchTimer { | |
| let startTime:CFAbsoluteTime | |
| var endTime:CFAbsoluteTime? | |
| init() { | |
| startTime = CFAbsoluteTimeGetCurrent() | |
| } | |
| func stop() -> CFAbsoluteTime { | |
| endTime = CFAbsoluteTimeGetCurrent() | |
| return duration! | |
| } | |
| var duration:CFAbsoluteTime? { | |
| if let endTime = endTime { | |
| return endTime - startTime | |
| } else { | |
| return nil | |
| } | |
| } | |
| } | |
| let timer = ParkBenchTimer() | |
| //var s = SampleGrid(data:sampleGrid) | |
| //The task took 0.00548702478408813 seconds. | |
| //var s2 = SampleGrid(data:sampleGrid2) | |
| //The task took 0.00878101587295532 seconds. | |
| var s3 = SampleGrid(data:sampleGrid3) | |
| //The task took 0.0197870135307312 seconds. | |
| // ... a long runnig task ... | |
| print("The task took \(timer.stop()) seconds.") | |
| */ | |
| import CoreFoundation | |
| // Usage: var timer = RunningTimer.init() | |
| // Start: timer.start() to restart the timer | |
| // Stop: timer.stop() returns the time and stops the timer | |
| // Duration: timer.duration returns the time | |
| // May also be used with print(" \(timer) ") | |
| struct RunningTimer: CustomStringConvertible { | |
| var begin:CFAbsoluteTime | |
| var end:CFAbsoluteTime | |
| init() { | |
| begin = CFAbsoluteTimeGetCurrent() | |
| end = 0 | |
| } | |
| mutating func start() { | |
| begin = CFAbsoluteTimeGetCurrent() | |
| end = 0 | |
| } | |
| mutating func stop() -> Double { | |
| if (end == 0) { end = CFAbsoluteTimeGetCurrent() } | |
| return Double(end - begin) | |
| } | |
| var duration:CFAbsoluteTime { | |
| get { | |
| if (end == 0) { return CFAbsoluteTimeGetCurrent() - begin } | |
| else { return end - begin } | |
| } | |
| } | |
| var description:String { | |
| let time = duration | |
| if (time > 100) {return " \(time/60) min"} | |
| else if (time < 1e-6) {return " \(time*1e9) ns"} | |
| else if (time < 1e-3) {return " \(time*1e6) µs"} | |
| else if (time < 1) {return " \(time*1000) ms"} | |
| else {return " \(time) s"} | |
| } | |
| } | |
| var timer = RunningTimer.init() | |
| //var s = SampleGrid(data:sampleGrid) | |
| // 4.89902496337891 ms | |
| // duration: 0.00516402721405029 | |
| var s2 = SampleGrid(data:sampleGrid2) | |
| // 8.18896293640137 ms | |
| //var s3 = SampleGrid(data:sampleGrid3) | |
| // 21.4249491691589 ms | |
| print(" \(timer) ") | |
| print(" \(timer.duration) ") | |
| /* | |
| Examples: | |
| Input Grid: | |
| let sampleGrid = [[0,1,0], [0,0,0], [1,0,0]] | |
| Console Output: | |
| 1 0 1 | |
| 2 2 1 | |
| 0 1 0 | |
| --------- | |
| Input Grid: | |
| let sampleGrid = [[0,1,0,0], [0,0,0,1], [1,0,0,1],[0,1,0,1]] | |
| Console Output: | |
| 1 0 2 1 | |
| 2 2 3 1 | |
| 1 2 4 2 | |
| 2 1 3 1 | |
| */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment