Skip to content

Instantly share code, notes, and snippets.

@vukcevich
Last active August 15, 2017 14:59
Show Gist options
  • Select an option

  • Save vukcevich/b0ee809e8d186be22ab3df3fa1416ec3 to your computer and use it in GitHub Desktop.

Select an option

Save vukcevich/b0ee809e8d186be22ab3df3fa1416ec3 to your computer and use it in GitHub Desktop.
Swift playground that takes an n x n grid of integers...
/*
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