Last active
December 17, 2021 04:31
-
-
Save proxpero/1caae4b5d05b26f7ab01 to your computer and use it in GitHub Desktop.
Rotating a matrix 90 degrees in place in Swift
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
//: Rotate a matrix 90 degrees in place | |
// "Write a function to rotate an NxN matrix by 90 degrees. You should rotate it in place, meaning you can't use another matrix to perform the rotation, but instead you have to use the same given structure." | |
// https://www.shiftedup.com/2015/05/10/programming-challenge-rotating-a-matrix-90-degrees-in-place | |
// This implementation of a matrix is taken from Apple's own. | |
// https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Subscripts.html | |
// The extensions are my own. | |
// Xcode 7.0, Swift 2.0 | |
public struct Matrix { | |
public init(rows: Int, columns: Int) { | |
self.rows = rows | |
self.columns = columns | |
grid = Array(count: rows * columns, repeatedValue: 0.0) | |
} | |
public subscript(row: Int, column: Int) -> Double { | |
get { | |
assert(indexIsValidForRow(row, column: column), "Index out of range") | |
return grid[(row * columns) + column] | |
} | |
set { | |
assert(indexIsValidForRow(row, column: column), "Index out of range") | |
grid[(row * columns) + column] = newValue | |
} | |
} | |
// MARK: Private | |
private let rows: Int, columns: Int | |
private var grid: [Double] | |
private func indexIsValidForRow(row: Int, column: Int) -> Bool { | |
return row >= 0 && row < rows && column >= 0 && column < columns | |
} | |
} | |
extension Matrix: Equatable {} | |
public func ==(lhs: Matrix, rhs: Matrix) -> Bool { | |
return lhs.grid == rhs.grid | |
} | |
extension Matrix { | |
mutating func fill() { | |
for i in (0..<rows * columns) { | |
grid[i] = Double(i) | |
} | |
} | |
} | |
extension Matrix { | |
mutating func rotate() { | |
let layers = (rows%2 == 0) ? rows/2 : (rows - 1)/2 // rows/2 also works but I trust it less | |
for layer in 0 ..< layers { | |
let first = layer | |
let last = rows - 1 - layer | |
for i in first..<last { | |
let top = (first, i) | |
let left = (last - (i - first), first) | |
let bottom = (last, last - (i - first)) | |
let right = (i, last) | |
let temp = self[top] | |
self[top] = self[left] | |
self[left] = self[bottom] | |
self[bottom] = self[right] | |
self[right] = temp | |
} | |
} | |
} | |
} | |
var target = Matrix(rows: 4, columns: 4) | |
target.grid = [12, 8, 4, 0, 13, 9, 5, 1, 14, 10, 6, 2, 15, 11, 7, 3] | |
var matrix = Matrix(rows: 4, columns: 4) | |
matrix.fill() | |
matrix.rotate() | |
assert(matrix == target) | |
matrix.rotate() | |
matrix.rotate() | |
matrix.rotate() | |
var target1 = Matrix(rows: 4, columns: 4) | |
target1.fill() | |
assert(target1 == matrix) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment