diff --git a/src/euler93/src/main.rs b/src/euler93/src/main.rs index 92359f8..e84eb7a 100644 --- a/src/euler93/src/main.rs +++ b/src/euler93/src/main.rs @@ -1,69 +1,115 @@ +use std::cmp::Ordering; + use itertools::Itertools; type Num = f64; +type Quadruple = [Num; 4]; + +const ALL_DIGITS: [Num; 10] = [0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]; fn main() { - let digits = Digits(1., 2., 3., 4.); + let mut digits_length = vec![]; - let mut all_possible_integers = digits.all_possible_integers(); + for quadruple_vec in ALL_DIGITS.into_iter().permutations(4) { + let quadruple = vec_to_quadruple(quadruple_vec); - all_possible_integers.sort(); + let digits = Digits(quadruple); - let mut result = 0; + let permutations = digits.permutations(); - for (i, num) in all_possible_integers.into_iter().enumerate() { - if i + 1 == num as usize { - result += 1; - } else { - break; - } - } -} + let mut results: Vec<_> = permutations + .into_iter() + .flat_map(find_integer_results) + .collect(); -fn recurse(array: &[Num]) -> Vec { - if array.len() == 2 { - let [a, b] = array else { panic!() }; - - let mut v = vec![]; - - for ops in Operations::iter() { - v.push(ops(*a, *b)); - } - v - } else { - let a = array[0]; - let b = array[1]; - - let mut v = vec![]; - - for ops in Operations::iter() { - v.push(ops(a, b)); - } - } -} - -struct Digits(Num, Num, Num, Num); - -impl Digits { - fn all_possible_integers(&self) -> Vec { - let array = [self.0, self.1, self.2, self.3]; - - array.into_iter().permutations(4).next().map(|a| { - for ops in Operations::iter() { - let x = ops(a[0], a[1]); + results.sort_unstable_by(|n1, n2| { + if n1 < n2 { + Ordering::Less + } else { + Ordering::Greater } }); - // dbg!(v); + let result = results + .into_iter() + .tuple_windows() + .filter(|(v0, v1)| (v1 - v0) > Num::EPSILON) + .map(|(n1, _)| n1) // TODO last number may be missing? + .collect_vec(); - todo!() + let length = number_consecutive_positive_integers(result); - // let outcomes: Vec<_> = Operations::new() - // .map(|f| f(a, b) as u32) - // .filter(|i| *i > 0) - // .collect(); + digits_length.push((quadruple, length)); + } - // dbg!(outcomes) + digits_length.sort_unstable_by(|a, b| a.1.cmp(&b.1)); + + let mut result = digits_length.last().unwrap().0; + + result.sort_by(Num::total_cmp); + + let s: String = result + .into_iter() + .map(|d| char::from_digit(d as u32, 10).unwrap()) + .collect(); + + println!("{s}"); +} + +fn number_consecutive_positive_integers(result: Vec) -> usize { + let length = result.len(); + + result + .into_iter() + .tuple_windows() + .filter(|(a, b)| b - 1.5 > *a) + .map(|(a, _)| a.round() as usize) + .next() + .unwrap_or(length) +} + +fn find_integer_results(quadruple: Quadruple) -> Vec { + let [i0, i1, i2, i3] = quadruple; + + let mut result = vec![]; + + for op1 in Operations::iter() { + for op2 in Operations::iter() { + for op3 in Operations::iter() { + let num = op3(op2(op1(i0, i1), i2), i3); + if num > 0. && is_integer(num) { + result.push(num); + } + } + } + } + + result +} + +fn is_integer(num: Num) -> bool { + (num.round() - num).abs() <= Num::EPSILON +} + +struct Digits(Quadruple); + +impl Digits { + fn permutations(&self) -> Vec { + self.0 + .into_iter() + .permutations(4) + .map(vec_to_quadruple) + .collect() + } +} + +fn vec_to_quadruple(v: Vec) -> Quadruple { + unsafe { + let i0 = *v.get_unchecked(0); + let i1 = *v.get_unchecked(1); + let i2 = *v.get_unchecked(2); + let i3 = *v.get_unchecked(3); + [i0, i1, i2, i3] } } @@ -72,7 +118,7 @@ struct Operations { } impl Iterator for Operations { - type Item = Box Num>; + type Item = Box Num>; fn next(&mut self) -> Option { self.last += 1;