use std::collections::{HashMap, HashSet}; use utils::{ fraction::Fraction, number::{Number, Sign}, }; fn main() { println!("Start"); let mut longest = (0, 0); for denominator in 2..1000 { let f = Fraction::new(1.into(), denominator.into()).unwrap(); if let Some(rep) = get_recurring(&f) { if longest.1 < rep.digits.len() { longest = (denominator, rep.digits.len()); } } } println!("longest {}", longest.0); } pub fn get_recurring(fraction: &Fraction) -> Option { let mut div_memory = HashMap::new(); let mut rem_memory = HashSet::new(); rem_memory.insert(1.into()); let mut div_with = fraction.numerator.clone(); let mut rational = Vec::new(); if div_with < fraction.denominator { div_with = div_with * 10; } loop { while div_with < fraction.denominator { rational.push(0); div_memory .entry(0) .and_modify(|value| *value += 1) .or_insert(1); div_with = div_with * 10; rem_memory.insert(div_with.clone()); } let (div, rem) = Number::div_with_rem(div_with.clone(), fraction.denominator.clone()).unwrap(); if rem == 0.into() { return None; } let next_digit = div.digits[0]; if div_memory.contains_key(&next_digit) && rem_memory.contains(&rem) && next_digit != 0 { let mut digits = vec![]; if div_memory.values().min() != div_memory.values().max() { rational.push(div.digits[0]); digits = rational; let (l, r) = digits.split_at(digits.len() / 2); if l == r { digits = l.to_vec(); } } else { let idx = rational .iter() .position(|digit| digit == &div.digits[0]) .unwrap(); if idx == rational.len() - 1 { digits.push(div.digits[0]); } else { for digit in &rational[idx..] { if digits.contains(digit) { break; } digits.push(*digit); } } } return Some(Number { digits, sign: Sign::Positif, }); } div_memory .entry(next_digit) .and_modify(|count| *count += 1) .or_insert(1); rem_memory.insert(rem.clone()); rational.push(div.digits[0]); div_with = rem * 10; } } #[cfg(test)] mod test { use utils::{fraction::Fraction, number::Number}; use crate::get_recurring; #[test] fn test_1_div_2() { let f = Fraction::new(1.into(), 2.into()).unwrap(); let rep = get_recurring(&f); assert_eq!(rep, None); } #[test] fn test_1_div_6() { let f = Fraction::new(1.into(), 6.into()).unwrap(); let rep = get_recurring(&f); assert_eq!(rep, Some(Number::from("6"))); } #[test] fn test_1_div_7() { let f = Fraction::new(1.into(), 7.into()).unwrap(); let rep = get_recurring(&f); assert_eq!(rep, Some(Number::from("142857"))); } #[test] fn test_1_div_11() { let f = Fraction::new(1.into(), 11.into()).unwrap(); let rep = get_recurring(&f); assert_eq!(rep, Some(Number::from("09"))); } #[test] fn test_1_div_12() { let f = Fraction::new(1.into(), 12.into()).unwrap(); let rep = get_recurring(&f); assert_eq!(rep, Some(Number::from("3"))); } #[test] fn test_1_div_14() { let f = Fraction::new(1.into(), 14.into()).unwrap(); let rep = get_recurring(&f); assert_eq!(rep, Some(Number::from("714285"))); } #[test] fn test_1_div_101() { let f = Fraction::new(1.into(), 101.into()).unwrap(); let rep = get_recurring(&f); assert_eq!(rep, Some(Number::from("0099"))); } }