After lots of trial and error I finally got it, kinda bruteforcy but works, fast
This commit is contained in:
		@@ -1,19 +1,144 @@
 | 
				
			|||||||
use utils::fraction::Fraction;
 | 
					use std::collections::{HashMap, HashSet};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use utils::{
 | 
				
			||||||
 | 
					    fraction::Fraction,
 | 
				
			||||||
 | 
					    number::{Number, Sign},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn main() {
 | 
					fn main() {
 | 
				
			||||||
    println!("Start");
 | 
					    println!("Start");
 | 
				
			||||||
    let mut longest = (0, 0);
 | 
					    let mut longest = (0, 0);
 | 
				
			||||||
    for denominator in 7..13 {
 | 
					    for denominator in 2..1000 {
 | 
				
			||||||
        println!("1/{denominator}:");
 | 
					 | 
				
			||||||
        let f = Fraction {
 | 
					        let f = Fraction {
 | 
				
			||||||
            numerator: 1.into(),
 | 
					            numerator: 1.into(),
 | 
				
			||||||
            denominator: denominator.into(),
 | 
					            denominator: denominator.into(),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        let rep = f.get_repeating();
 | 
					        if let Some(rep) = get_recurring(&f) {
 | 
				
			||||||
        if longest.1 < rep.digits.len() {
 | 
					            if longest.1 < rep.digits.len() {
 | 
				
			||||||
            longest = (denominator, rep.digits.len());
 | 
					                longest = (denominator, rep.digits.len());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        println!("{rep}");
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    println!("longest {}", longest.0);
 | 
					    println!("longest {}", longest.0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn get_recurring(fraction: &Fraction) -> Option<Number> {
 | 
				
			||||||
 | 
					    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")));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user