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
use num::BigInt; use crate::CollatzType; pub type Collatz = CollatzType<BigInt>; impl From<i64> for Collatz { fn from(i: i64) -> Collatz { if i <= 0 { panic!("Input must be a positive integer!") } let n = BigInt::from(i); Collatz { start: n } } } impl From<BigInt> for Collatz { fn from(n: BigInt) -> Collatz { if n <= BigInt::from(0) { panic!("Input must be a positive integer!") } Collatz { start: n } } } impl Iterator for Collatz { type Item = BigInt; fn next(&mut self) -> Option<Self::Item> { let n = self.start.clone(); if n.clone() % 2 == BigInt::from(0) { self.start = n / 2; return Some(self.start.clone()); } else if n.clone() == BigInt::from(1) { return None; } else { self.start = n * 3 + 1; return Some(self.start.clone()); } } } #[cfg(test)] mod test { use super::*; #[test] #[should_panic] fn collatz_0() { let mut collatz = Collatz::from(0); assert_eq!(collatz.next(), None); } #[test] fn collatz_13() { let mut collatz = Collatz::from(13); assert_eq!(collatz.next(), Some(BigInt::from(40))); assert_eq!(collatz.next(), Some(BigInt::from(20))); assert_eq!(collatz.next(), Some(BigInt::from(10))); assert_eq!(collatz.next(), Some(BigInt::from(5))); assert_eq!(collatz.next(), Some(BigInt::from(16))); assert_eq!(collatz.next(), Some(BigInt::from(8))); assert_eq!(collatz.next(), Some(BigInt::from(4))); assert_eq!(collatz.next(), Some(BigInt::from(2))); assert_eq!(collatz.next(), Some(BigInt::from(1))); assert_eq!(collatz.next(), None); } }