|
| 1 | +use advent_of_code::into_group_map_heapless; |
| 2 | +use heapless::FnvIndexMap as HeaplessHashMap; |
| 3 | +use heapless::FnvIndexSet as HeaplessHashSet; |
| 4 | +use heapless::Vec as HeaplessVec; |
| 5 | +use itertools::Itertools; |
| 6 | +use mygrid::grid::Grid; |
| 7 | +use mygrid::point::Point; |
| 8 | +advent_of_code::solution!(8); |
| 9 | + |
| 10 | +const MAX_ANTENNA_TYPES: usize = 64; |
| 11 | +const MAX_ANTENNA_PER_TYPE: usize = 16; |
| 12 | +type AntennaMap<'a> = |
| 13 | + HeaplessHashMap<&'a char, HeaplessVec<Point, MAX_ANTENNA_PER_TYPE>, MAX_ANTENNA_TYPES>; |
| 14 | + |
| 15 | +fn solve<const PART1: bool>(input: &str) -> Option<u32> { |
| 16 | + let grid = Grid::new_char_grid_from_str(input); |
| 17 | + |
| 18 | + let antennas: AntennaMap = into_group_map_heapless( |
| 19 | + grid.iter_item_and_position() |
| 20 | + .filter(|(_, &c)| c != '.') |
| 21 | + .map(|(point, c)| (c, point)), |
| 22 | + ); |
| 23 | + |
| 24 | + let mut pos_set: HeaplessHashSet<Point, 2048> = HeaplessHashSet::new(); |
| 25 | + for (_, vec) in antennas.iter() { |
| 26 | + for (a, b) in vec.iter().tuple_combinations() { |
| 27 | + for (a, b) in [(a, b), (b, a)] { |
| 28 | + let dir = b.as_vector_direction(a); |
| 29 | + let mut p = *a + dir; |
| 30 | + if PART1 { |
| 31 | + if grid.is_in_bounds(p) { |
| 32 | + pos_set.insert(p).unwrap(); |
| 33 | + } |
| 34 | + } else { |
| 35 | + pos_set.insert(*a).unwrap(); |
| 36 | + pos_set.insert(*b).unwrap(); |
| 37 | + while grid.is_in_bounds(p) { |
| 38 | + pos_set.insert(p).unwrap(); |
| 39 | + p = p + dir; |
| 40 | + } |
| 41 | + } |
| 42 | + } |
| 43 | + } |
| 44 | + } |
| 45 | + |
| 46 | + Some(pos_set.len() as u32) |
| 47 | +} |
| 48 | +pub fn part_one(input: &str) -> Option<u32> { |
| 49 | + solve::<true>(input) |
| 50 | +} |
| 51 | + |
| 52 | +pub fn part_two(input: &str) -> Option<u32> { |
| 53 | + solve::<false>(input) |
| 54 | +} |
| 55 | + |
| 56 | +#[cfg(test)] |
| 57 | +mod tests { |
| 58 | + use super::*; |
| 59 | + |
| 60 | + #[test] |
| 61 | + fn test_part_one() { |
| 62 | + let result = part_one(&advent_of_code::template::read_file("examples", DAY)); |
| 63 | + assert_eq!(result, Some(14)); |
| 64 | + } |
| 65 | + |
| 66 | + #[test] |
| 67 | + fn test_part_two() { |
| 68 | + let result = part_two(&advent_of_code::template::read_file("examples", DAY)); |
| 69 | + assert_eq!(result, Some(34)); |
| 70 | + } |
| 71 | +} |
0 commit comments