Last active
December 14, 2017 17:05
-
-
Save ffried/eb53a5de6cd6d681ac41e1de270a29be to your computer and use it in GitHub Desktop.
Fibonacci.swift
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
public struct Fibonacci<Number: FixedWidthInteger>: Sequence { | |
public let startsAtZero: Bool | |
public init(startAtZero: Bool = true) { | |
startsAtZero = startAtZero | |
} | |
public func makeIterator() -> Iterator { | |
return .first(startsAtZero: startsAtZero) | |
} | |
} | |
extension Fibonacci { | |
public enum Iterator: IteratorProtocol { | |
public typealias Element = Number | |
case first(startsAtZero: Bool) | |
case second(last: Element) | |
case any(secondLast: Element, last: Element) | |
public mutating func next() -> Element? { | |
let next: Element | |
switch self { | |
case .first(let startsAtZero): | |
next = startsAtZero ? 0 : 1 | |
self = .second(last: next) | |
case .second(let last): | |
next = 1 | |
self = .any(secondLast: last, last: next) | |
case .any(let secondLast, let last): | |
// Prevent overflow | |
guard case let (nextValue, overflow) = secondLast.addingReportingOverflow(last), | |
!overflow else { return nil } | |
next = nextValue | |
self = .any(secondLast: last, last: next) | |
} | |
return next | |
} | |
} | |
} | |
let fibonacci = Fibonacci<Int>() | |
for num in fibonacci where num < 100 { | |
print(num) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment