Skip to content
Fetching contributors… Cannot retrieve contributors at this time
149 lines (123 sloc) 5.05 KB
 //: [Previous](@previous) /* Find a human-friendly explanation of this coding challenge at http://pabloduo.com/2018/09/22 Write a data structure that takes as input an `n x n` 2-dimensional array, and rotates the array by 90 degrees clockwise. EXAMPLE: Input: [[ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11, 12], [13, 14, 15, 16]] Output: [13, 9, 5, 1, 14, 10, 6, 2, 15, 11, 7, 3, 16, 12, 8, 4] */ /// Wrapper type struct to provide clockwise-rotated access /// to the elements of the original 2D array (eq. matrix). struct RotatedMatrix: Collection { /// Copy of the original matrix. let matrix: [[Element]] /// Shorthand to the matrix's elements count. var size: Int { return matrix.count } /// The position of the first element in a nonempty collection. /// /// If the collection is empty, `startIndex` is equal to `endIndex`. var startIndex: Int { return matrix.startIndex } /// The collection's "past the end" position---that is, the /// position one greater than the last valid subscript argument. /// /// If the collection is empty, `endIndex` is equal to `startIndex`. var endIndex: Int { return size * size } /// Accesses the element at the specified position. /// /// You can subscript a collection with any valid index other than /// the collection's end index. The end index refers to the position /// one past the last element of a collection, so it doesn't /// correspond with an element. /// /// - Parameter position: The position of the element to access. /// `position` must be a valid index of the collection that is /// not equal to the `endIndex` property. /// /// - Complexity: O(1) subscript(position: Int) -> Element { // Guard access beyond boundaries of the original matrix precondition(position < endIndex, "Can't subscript an element in position beyond endIndex") // Compute start and offset based on the current position let start = size - 1, offset = position % size // Translate position into coordinates of the matrix let x = start - offset, y = position / size print("offset = \(offset), x= \(x), y = \(y)") // Query element from the original matrix return matrix[x][y] } /// Returns the position immediately after the given index. /// /// - Parameter i: A valid index of the collection. `i` must be less than /// `endIndex`. /// - Returns: The index value immediately after `i`. func index(after i: Int) -> Int { // Guard access beyond boundaries of the original matrix precondition(i < endIndex, "Can't advance beyond endIndex") // Advance to the next element return i + 1 } } /// Conform to Equatable protocol for testing purposes. extension RotatedMatrix: Equatable { /// Returns a Boolean value indicating whether two values are equal. /// /// Equality is the inverse of inequality. For any values `a` and `b`, /// `a == b` implies that `a != b` is `false`. /// /// - Parameters: /// - lhs: A value to compare. /// - rhs: Another value to compare. static func == (lhs: RotatedMatrix, rhs: [[Element]]) -> Bool { // Verify sequences are of the same length if lhs.endIndex != total(array: rhs) { return false } // Enumerate sequences and compare elements let size = rhs.count for i in 0...size - 1 { for j in 0...size - 1 { // Translate coordinates of a matrix into a flat array let x = (i * size) + j // Actual comparison if lhs[x] != rhs[i][j] { return false } } } // Looks like both sequences are equal return true } } /// Returns an iconographic value (✅ or ❌) indicating whether the specified /// test assertion has passed or failed. /// /// - Parameter lhs: An actual value to compare with. /// - Parameter rhs: An expected value to compare with. func ?>>(lhs: RotatedMatrix, rhs: [[Int]]) -> Icon { // Simple comparison is enough return lhs == rhs ? PASS : FAIL } // Assert a few basic test cases RotatedMatrix(matrix: MX0) ?>> MO0 RotatedMatrix(matrix: MX1) ?>> MO1 RotatedMatrix(matrix: MX2) ?>> MO2 RotatedMatrix(matrix: MX3) ?>> MO3 // Assert a few advanced test cases RotatedMatrix(matrix: MX4) ?>> MO4 RotatedMatrix(matrix: MX5) ?>> MO5 RotatedMatrix(matrix: MX6) ?>> MO6 RotatedMatrix(matrix: MX7) ?>> MO7 RotatedMatrix(matrix: MX8) ?>> MO8 RotatedMatrix(matrix: MX9) ?>> MO9 // Assert a few advanced test cases RotatedMatrix(matrix: MX10) ?>> MO10 RotatedMatrix(matrix: MX11) ?>> MO11 RotatedMatrix(matrix: MX12) ?>> MO12 RotatedMatrix(matrix: MX13) ?>> MO13 RotatedMatrix(matrix: MX14) ?>> MO14 RotatedMatrix(matrix: MX15) ?>> MO15 RotatedMatrix(matrix: MX16) ?>> MO16 RotatedMatrix(matrix: MX17) ?>> MO17 RotatedMatrix(matrix: MX18) ?>> MO18 RotatedMatrix(matrix: MX19) ?>> MO19 RotatedMatrix(matrix: MX20) ?>> MO20 //: [Next](@next)
You can’t perform that action at this time.