Last active
December 26, 2015 22:12
-
-
Save romainmenke/96e10f3163a16af1f773 to your computer and use it in GitHub Desktop.
This file contains 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
struct RMMatrix<Element> { | |
private var values : [[Element]] = [] | |
var rows : [[Element]] { | |
get { | |
return values | |
} | |
set(value) { | |
values = value | |
} | |
} | |
init(rows: [[Element]]) { | |
self.rows = rows | |
} | |
init(columns: [[Element]]) { | |
self.columns = columns | |
} | |
var columns : [[Element]] { | |
get { | |
if values.isEmpty { | |
return [[]] | |
} | |
return rowsToColumns(rows) | |
} | |
set(value) { | |
values = rowsToColumns(value) | |
} | |
} | |
private func rowsToColumns(rows:[[Element]]) -> [[Element]] { | |
guard let first = rows.first else { | |
return [[]] | |
} | |
var newColumns : [[Element]] = [] | |
for colIndex in 0..<first.count { | |
var column : [Element] = [] | |
for row in rows { | |
if row.count > colIndex { | |
column.append(row[colIndex]) | |
} | |
} | |
newColumns.append(column) | |
} | |
return newColumns | |
} | |
subscript(row:Int) -> [Element] { | |
get { | |
return rows[row] | |
} | |
set(value) { | |
self.values[row] = value | |
} | |
} | |
subscript(row:Int,_ column:Int) -> Element? { | |
get { | |
guard rows.count > row else { | |
return nil | |
} | |
guard rows[row].count > column else { | |
return nil | |
} | |
return rows[row][column] | |
} | |
set(value) { | |
guard rows.count > row else { | |
return | |
} | |
guard rows[row].count > column else { | |
return | |
} | |
self.values[row][column] = value ?? self.values[row][column] | |
} | |
} | |
func reverse() -> RMMatrix<Element> { | |
var reversed : [[Element]] = [] | |
for row in self.rows { | |
reversed.append(row.reverse()) | |
} | |
return RMMatrix(rows: reversed) | |
} | |
func flip() -> RMMatrix<Element> { | |
var reversed : [[Element]] = [] | |
for column in self.columns { | |
reversed.append(column.reverse()) | |
} | |
return RMMatrix(columns: reversed) | |
} | |
func reversedFlip() -> RMMatrix<Element> { | |
return self.flip().reverse() | |
} | |
} | |
extension RMMatrix where Element : Equatable { | |
func contains(element:Element) -> Bool { | |
for row in self.rows { | |
if row.contains(element) { | |
return true | |
} | |
} | |
return false | |
} | |
func rowsContainDuplicates() -> Bool { | |
for row in self.rows { | |
if row.containsDuplicates() { | |
return true | |
} | |
} | |
return false | |
} | |
func columnsContainDuplicates() -> Bool { | |
for column in self.columns { | |
if column.containsDuplicates() { | |
return true | |
} | |
} | |
return false | |
} | |
} | |
extension RMMatrix { | |
func isSquare() -> Bool { | |
guard rows.count == columns.count else { | |
return false | |
} | |
if let rowsLength = rows.first?.count { | |
for row in rows { | |
if row.count != rowsLength { | |
return false | |
} | |
} | |
} | |
if let columnsLength = columns.first?.count { | |
for column in columns { | |
if column.count != columnsLength { | |
return false | |
} | |
} | |
} | |
return true | |
} | |
} | |
extension Array where Element : _ArrayType { | |
func matrix() -> RMMatrix<Element.Element> { | |
var arrays : [[Element.Element]] = [] | |
for nest in self { | |
if let array = nest as? Array<Element.Element> { | |
arrays.append(array) | |
} | |
} | |
return RMMatrix(rows: arrays) | |
} | |
} | |
extension Array where Element : Equatable { | |
func containsDuplicates() -> Bool { | |
var remaining = self | |
var duplicates : Bool = false | |
while let pop = remaining.popLast() { | |
if remaining.contains(pop) { | |
duplicates = true | |
break | |
} | |
} | |
return duplicates | |
} | |
func indexOfDuplicate() -> Int? { | |
guard let dupe = self.duplicate() else { | |
return nil | |
} | |
return self.indexOf(dupe) | |
} | |
func duplicate() -> Element? { | |
guard self.containsDuplicates() else { | |
return nil | |
} | |
var remaining = self | |
var element : Element? = nil | |
while let pop = remaining.popLast() { | |
if remaining.contains(pop) { | |
element = pop | |
break | |
} | |
} | |
return element | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment