Created
August 6, 2015 16:42
-
-
Save jtbandes/7e5560183b420563adae 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
// Much safer! Notice that `iteration` stops increasing after the initial terms are produced. | |
// Thanks @oisdk for pointing this out. | |
public struct RecurrenceRelation<Element>: SequenceType, GeneratorType | |
{ | |
private let recurrence: (T: [Element], n: Int) -> Element | |
private var storage: [Element] | |
/// - Parameter initialTerms: The first terms of the sequence. | |
/// The `count` of this array is the **order** of the recurrence. | |
/// - Parameter recurrence: Produces the `n`th term from the previous terms. | |
public init(_ initialTerms: [Element], _ recurrence: (T: [Element], n: Int) -> Element) | |
{ | |
self.recurrence = recurrence | |
storage = initialTerms | |
} | |
// SequenceType requirement | |
public func generate() -> RecurrenceRelation<Element> { return self } | |
// GeneratorType requirement | |
private var iteration = 0 | |
public mutating func next() -> Element? | |
{ | |
// Produce all the initial terms first. | |
if iteration < storage.count { return storage[iteration++] } | |
// Call the closure with a pointer offset from the actual memory location, | |
// so that T[n-1] is the last element in the array. | |
let newValue = recurrence(T: storage, n: iteration) | |
// Store the next value, dropping the oldest one. | |
storage.removeAtIndex(0) | |
storage.append(newValue) | |
return newValue | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment