Advent of Code solutions
at main 77 lines 2.4 kB view raw
1use core::ops::Range; 2use std::{collections::HashMap, hash::Hash}; 3 4pub fn counts<T: Hash + Eq + PartialEq>(l: impl Iterator<Item = T>) -> HashMap<T, u64> { 5 let (min, max) = l.size_hint(); 6 l.fold( 7 HashMap::with_capacity(max.unwrap_or(min)), 8 |mut agg, curr| { 9 agg.entry(curr).and_modify(|x| *x += 1).or_insert(1); 10 agg 11 }, 12 ) 13} 14 15#[derive(Debug, Eq, PartialEq, Clone, Copy)] 16pub enum FollowRangeResult { 17 InvalidPair(i64, i64), 18 Increasing, 19 Decreasing, 20 Fluctuates, 21 ListTooShort, 22} 23 24pub fn follows_diff_range( 25 l: &[i64], 26 diff_range: Range<i64>, 27 enforce_one_way: bool, 28 allow_eq: bool, 29) -> FollowRangeResult { 30 if l.len() < 2 { 31 FollowRangeResult::ListTooShort 32 } else { 33 let first_diff = l[1] - l[0]; 34 if diff_range.contains(&first_diff) { 35 let mut ordering = FollowRangeResult::Fluctuates; 36 37 let failing_pair = l.windows(2).skip(1).find_map(|w| { 38 let (x, y) = (w[0], w[1]); 39 let diff = y - x; 40 if diff_range.contains(&diff) && (allow_eq || diff != 0) { 41 if ordering == FollowRangeResult::Fluctuates && diff != 0 { 42 ordering = if diff < 0 { 43 FollowRangeResult::Decreasing 44 } else { 45 FollowRangeResult::Increasing 46 }; 47 None 48 } else if enforce_one_way 49 && (ordering == FollowRangeResult::Increasing && diff < 0) 50 || (ordering == FollowRangeResult::Decreasing && diff > 0) 51 { 52 Some((x, y)) 53 } else { 54 None 55 } 56 } else { 57 Some((x, y)) 58 } 59 }); 60 61 match failing_pair { 62 Some((x, y)) => FollowRangeResult::InvalidPair(x, y), 63 None => ordering, 64 } 65 } else { 66 FollowRangeResult::InvalidPair(l[0], l[1]) 67 } 68 } 69} 70 71pub fn all_combos_remove_one<T>(l: &[T]) -> impl Iterator<Item = impl Iterator<Item = &T>> { 72 (0..l.len()).map(|exclude| { 73 l.iter() 74 .enumerate() 75 .filter_map(move |(i, e)| Some(e).filter(|_| i != exclude)) 76 }) 77}