use std::collections::VecDeque; use crate::utils; pub fn task1() { println!("{}", solve(&utils::read_file("input/day25.txt"))); } fn solve(input: &str) -> u32 { let mut points: Vec = input.lines().map(STP::from).collect(); let mut constellations = 0; while let Some(next_origin) = points.pop() { constellations += 1; let mut queue = VecDeque::new(); queue.push_back(next_origin); while let Some(next) = queue.pop_front() { let (neighbors, remainder) = points.into_iter().partition(|p| next.is_neighbor_to(p)); points = remainder; for n in neighbors { queue.push_back(n); } } } constellations } #[derive(Hash, Eq, PartialEq, Debug)] struct STP(i32, i32, i32, i32); impl STP {} impl STP { fn neighbors(&self) -> Vec { let mut result = Vec::new(); for x in -3..=3 { for y in -3..=3 { for z in -3..=3 { for t in -3..=3 { let candidate = STP(self.0 + x, self.1 + y, self.2 + z, self.3 + t); if self.is_neighbor_to(&candidate) { result.push(candidate); } } } } } result } fn distance(&self, other: &Self) -> u32 { ((self.0 - other.0).abs() + (self.1 - other.1).abs() + (self.2 - other.2).abs() + (self.3 - other.3).abs()) as u32 } fn is_neighbor_to(&self, other: &Self) -> bool { self.distance(other) <= 3 } } impl From<&str> for STP { fn from(value: &str) -> Self { let mut split = value.split(","); STP( split.next().unwrap().parse().unwrap(), split.next().unwrap().parse().unwrap(), split.next().unwrap().parse().unwrap(), split.next().unwrap().parse().unwrap(), ) } } mod test { use crate::tasks::day25::solve; #[test] fn example1() { let input = "0,0,0,0 3,0,0,0 0,3,0,0 0,0,3,0 0,0,0,3 0,0,0,6 9,0,0,0 12,0,0,0"; assert_eq!(solve(input), 2); } #[test] fn example2() { let input = "-1,2,2,0 0,0,2,-2 0,0,0,-2 -1,2,0,0 -2,-2,-2,2 3,0,2,-1 -1,3,2,2 -1,0,-1,0 0,2,1,-2 3,0,0,0"; assert_eq!(solve(input), 4); } #[test] fn example3() { let input = "1,-1,0,1 2,0,-1,0 3,2,-1,0 0,0,3,1 0,0,-1,-1 2,3,-2,0 -2,2,0,0 2,-2,0,-1 1,-1,0,-1 3,2,0,2 "; assert_eq!(solve(input), 3); } #[test] fn example4() { let input = "1,-1,-1,-2 -2,-2,0,1 0,2,1,3 -2,3,-2,1 0,2,3,-2 -1,-1,1,-2 0,-2,-1,0 -2,2,3,-1 1,2,2,0 -1,-2,0,-2 "; assert_eq!(solve(input), 8); } }