package prodfib class FibonacciPairs : Iterable> { private class FibonacciPairsIterator : Iterator> { private var a: Long = 0 private var b: Long = 1 /** * Returns `true` if the iteration has more elements. */ override fun hasNext(): Boolean = true /** * Returns the next element in the iteration. */ override fun next(): Pair { val current = a to b a = current.second b = current.first + current.second return current } } /** * Returns an iterator over the elements of this object. */ override fun iterator(): Iterator> = FibonacciPairsIterator() } fun productFib(prod: Long): LongArray = FibonacciPairs() .asSequence() .dropWhile { (a, b) -> a * b < prod } .first() .let { (a, b) -> longArrayOf( a, b, if (a * b == prod) { 1 } else { 0 } ) } fun main() { (0 until 10).zip(FibonacciPairs()).forEach { (i, pair) -> println("$i → $pair") } val tests = mapOf( 4895L to longArrayOf(55, 89, 1), 5895L to longArrayOf(89, 144, 0), 714L to longArrayOf(21, 34, 1), 800L to longArrayOf(34, 55, 0), ) tests.forEach { (prod, expected) -> check(productFib(prod).contentEquals(expected)) } }