From 36cac2538cac969f213141a71ef6678e47853ffc Mon Sep 17 00:00:00 2001 From: timeshifter Date: Sat, 15 Mar 2025 16:26:09 +0100 Subject: [PATCH] add 27 --- src/euler26/Cargo.toml | 8 ++++ src/euler26/src/main.rs | 89 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 src/euler26/Cargo.toml create mode 100644 src/euler26/src/main.rs diff --git a/src/euler26/Cargo.toml b/src/euler26/Cargo.toml new file mode 100644 index 0000000..4a46846 --- /dev/null +++ b/src/euler26/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "euler26" +version = "0.1.0" +edition = "2021" + +[dependencies] +itertools = "0.14.0" +rug = "*" diff --git a/src/euler26/src/main.rs b/src/euler26/src/main.rs new file mode 100644 index 0000000..4cdbae7 --- /dev/null +++ b/src/euler26/src/main.rs @@ -0,0 +1,89 @@ +use itertools::Itertools; +use rug::Float; + +const PRECISION: u32 = 16_192; +const MIN: usize = 2; +const MAX: usize = 1_000; + +fn main() { + let mut largest_number = 1; + let mut largest_len = 1; + + for number in MIN..MAX { + println!("{number}"); + if let Some(value) = find_cycle_length(number as f64) { + if value > largest_len { + largest_len = value; + largest_number = number; + } + } + } + + println!("{largest_number}: {largest_len}"); +} + +fn find_cycle_length(number: f64) -> Option { + let n = Float::with_val(PRECISION, 1.); + let d = Float::with_val(PRECISION, number); + let r = n / d; + let s = r.to_string(); + + let max_length = s.len() / 3; + + let s = sanitize_string(s); + + for skip in 0..max_length { + for length in 1..max_length { + let chunks = s.chars().skip(skip).chunks(length); + let mut iter = chunks.into_iter(); + + let first: String = iter.next().unwrap().collect(); + let second: String = iter.next().unwrap().collect(); + let third: String = iter.next().unwrap().collect(); + + if first == second && second == third { + return Some(length); + } + } + } + None +} + +fn sanitize_string(s: String) -> String { + let exponent = s.chars().last().unwrap().to_digit(10).unwrap(); + + let mut s: String = s + .chars() + .take_while(|c| !c.is_ascii_lowercase()) + .filter(|c| *c != '.') + .collect(); + + let add_leading_zeros = exponent - 1; + for _ in 0..add_leading_zeros { + s.insert(0, '0'); + } + s +} + +#[cfg(test)] +mod tests { + use crate::find_cycle_length; + + #[test] + fn case_3() { + let result = find_cycle_length(3.); + assert_eq!(result, Some(1)) + } + + #[test] + fn case_6() { + let result = find_cycle_length(6.); + assert_eq!(result, Some(1)) + } + + #[test] + fn case_7() { + let result = find_cycle_length(7.); + assert_eq!(result, Some(6)) + } +}