Instantly share code, notes, and snippets.

Embed
What would you like to do?
// 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