use std::iter; // Calculating a continued fraction is quite easy with iterators, however // writing a proper iterator adapter is less so. We settle for a macro which // for most purposes works well enough. // // One limitation with this iterator based approach is that we cannot reverse // input iterators since they are not usually DoubleEnded. To circumvent this // we can collect the elements and then reverse them, however this isn't ideal // as we now have to store elements equal to the number of iterations. // // Another is that iterators cannot be resused once consumed, so it is often // required to make many clones of iterators. macro_rules! continued_fraction { ($a:expr, $b:expr ; $iterations:expr) => ( ($a).zip($b) .take($iterations) .collect::>().iter() .rev() .fold(0 as f64, |acc: f64, &(x, y)| { x as f64 + (y as f64 / acc) }) ); ($a:expr, $b:expr) => (continued_fraction!($a, $b ; 1000)); } fn main() { // Sqrt(2) let sqrt2a = (1..2).chain(iter::repeat(2)); let sqrt2b = iter::repeat(1); println!("{}", continued_fraction!(sqrt2a, sqrt2b)); // Napier's Constant let napiera = (2..3).chain(1..); let napierb = (1..2).chain(1..); println!("{}", continued_fraction!(napiera, napierb)); // Pi let pia = (3..4).chain(iter::repeat(6)); let pib = (1i64..).map(|x| (2 * x - 1).pow(2)); println!("{}", continued_fraction!(pia, pib)); }