1
1
mirror of https://github.com/github/semantic.git synced 2024-12-22 14:21:31 +03:00
semantic/prototype/Doubt/Matrix.swift
2015-11-12 15:26:50 -05:00

56 lines
1.7 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/// A two-dimensional matrix of memoized values.
///
/// These values are populated by a function from the coordinates of a given cell to the matrixs element type.
///
/// Values are retrieved by subscripting with row/column indices. Out-of-bound indices produce `nil` values, rather than asserting.
public struct Matrix<A, I: ForwardIndexType> {
public init(across: Range<I>, down: Range<I>, compute: (I, I) -> A) {
self.init(across: across, down: down, values: constructRowMajor(across, down: down, forEach: { i, j in Memo { compute(i, j) } }))
}
public let across: Range<I>
public let down: Range<I>
private let width: I.Distance
private let values: [Memo<A>]
public subscript (i: I, j: I) -> Memo<A>? {
guard i != across.endIndex && j != down.endIndex else { return nil }
let i = across.startIndex.distanceTo(i)
let j = down.startIndex.distanceTo(j)
return values[Int((i + j * width).toIntMax())]
}
// MARK: Functor
public func map<Other>(transform: A -> Other) -> Matrix<Other, I> {
return Matrix<Other, I>(across: across, down: down, values: values.map { $0.map(transform) })
}
// MARK: Implementation details
private init(across: Range<I>, down: Range<I>, values: [Memo<A>]) {
self.across = across
self.down = down
self.values = values
self.width = across.count
}
}
/// Constructs a row-major ordering of values produced with `forEach`.
private func constructRowMajor<A, I: ForwardIndexType>(across: Range<I>, down: Range<I>, @noescape forEach: (I, I) -> A) -> [A] {
var values: [A] = []
values.reserveCapacity(Int(across.count.toIntMax()) * Int(down.count.toIntMax()))
for j in down {
for i in across {
values.append(forEach(i, j))
}
}
return values
}
import Memo