diff --git a/src/euler94/src/main.rs b/src/euler94/src/main.rs index 527b02f..f6a0fa2 100644 --- a/src/euler94/src/main.rs +++ b/src/euler94/src/main.rs @@ -1,34 +1,32 @@ -use f128::f128; -use num_traits::Float; - -type Num = f128; - -static mut ONE_BILLION: Num = f128::ZERO; -const ONE: Num = f128::ONE; +type Num = usize; fn main() { - unsafe { - ONE_BILLION = f128::from(1_000_000_000.); - } + let mut sum = 0; - let mut sum = f128::ZERO; + let mut i = 5; + 'outer: loop { + if i > 333_333_334 { + break; + } + let a = i; - 'outer: for i in 2.. { - let a = f128::from(i); + if a % 2 == 0 { + i += 1; + continue; + } - for c in [a - ONE, a + ONE] { + for c in [a - 1, a + 1] { let t = Triangle::new(a, c); - let p = t.perimeter(); - - if unsafe { p > ONE_BILLION } { - break 'outer; - } if t.has_integer_area() { println!("{:.10}, {:.10}", t.a, t.c); - sum += p; + sum += t.perimeter(); + i = ((i as f64) * 3.59).trunc() as usize; + continue 'outer; } } + + i += 1; } println!("{sum:.15}"); @@ -45,21 +43,13 @@ impl Triangle { } fn perimeter(&self) -> Num { - Num::TWO * self.a + self.c + 2 * self.a + self.c } fn has_integer_area(&self) -> bool { - is_integer(self.area()) - } + let h = 4 * self.a.pow(2) - self.c.pow(2); + let root = (h as f64).sqrt().trunc() as usize; - fn area(&self) -> Num { - let a = self.a; - let c = self.c; - - c / Num::from(4.) * (Num::from(4.) * a.powi(2) - c.powi(2)).sqrt() + root * root == h } } - -fn is_integer(x: Num) -> bool { - (x.round() - x).abs() <= Num::EPSILON -}