Skip to content

Instantly share code, notes, and snippets.

@proxpero
Last active December 17, 2021 04:31
Show Gist options
  • Save proxpero/1caae4b5d05b26f7ab01 to your computer and use it in GitHub Desktop.
Save proxpero/1caae4b5d05b26f7ab01 to your computer and use it in GitHub Desktop.
Rotating a matrix 90 degrees in place in Swift
//: 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