1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
mod bigcollatz{ use num_bigint::{BigUint}; use num_traits::{Zero, One}; use std::ops::{Add, Mul, Div}; use num_bigint::ToBigUint; pub struct BigCollatz { curr: BigUint, done: bool, pub start : BigUint, pub steps: u32, } pub struct CollatzStep{ pub step: u32, pub curr: BigUint, } impl BigCollatz { pub fn new(ini: BigUint) -> BigCollatz { BigCollatz { start: ini.clone(), curr: ini.clone(), steps: 0, done: false, } } } impl Iterator for BigCollatz { type Item = CollatzStep; fn next(&mut self) -> Option<CollatzStep> { if self.done { return None }; let one: BigUint = BigUint::one(); let zero: BigUint = BigUint::zero(); let two: BigUint = BigUint::from(2u32); let three: BigUint = BigUint::from(3u32); let curr = &self.curr; let result = curr.clone(); if curr % &two == zero{ self.curr = curr.div(&two); }else{ self.curr = curr.mul(&three).add(&one); } if self.curr <= one{ self.done = true } self.steps +=1; Some( CollatzStep{ step: self.steps, curr: result }) } } #[test] fn it_works() { let c = BigCollatz::new(100.to_biguint().unwrap() ); for x in c{ println!("n:{}, step:{}", x.curr, x.step); assert_eq!( x.curr > BigUint::one(), true ); } } }