Skip to content

Instantly share code, notes, and snippets.

@romainmenke
Last active December 26, 2015 22:12
Show Gist options
  • Save romainmenke/96e10f3163a16af1f773 to your computer and use it in GitHub Desktop.
Save romainmenke/96e10f3163a16af1f773 to your computer and use it in GitHub Desktop.
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