From: alex <> Date: Mon, 8 Dec 2025 17:56:02 +0000 (+0100) Subject: day08: part1 X-Git-Url: https://aoc.elinar.fr/?a=commitdiff_plain;h=7a5f1671023bc9c1e5891cd94e1ee20b52145b3c;p=aoc_2025 day08: part1 --- diff --git a/src/day08.rs b/src/day08.rs new file mode 100644 index 0000000..cdd2abb --- /dev/null +++ b/src/day08.rs @@ -0,0 +1,137 @@ +use std::error::Error; +use std::collections::HashSet; + +#[derive(Copy,Clone,Debug)] +struct Coord { + x: i64, + y: i64, + z: i64, +} + +impl Coord { + fn new(x: i64, y: i64, z: i64) -> Self { + Self { x, y, z } + } + + // Euclidean distance (not square rooted) + fn dst(&self, other: Self) -> i64 { + (self.x - other.x).pow(2) + (self.y - other.y).pow(2) + (self.z - other.z).pow(2) + } +} + +struct Puzzle { + boxes: Vec, +} + +impl Puzzle { + fn new(input: &str) -> Self { + let boxes = input.lines() + .map(|l| { + let coord: Vec = l.split(',') + .map(|v| v.parse::().unwrap()) + .collect(); + Coord::new(coord[0], coord[1], coord[2]) + }) + .collect(); + Self { boxes } + } + + fn part1(&self, n_shortest: usize) -> usize { + let mut connections: Vec<(i64, (usize, usize))> = Vec::new(); + for i in 0..self.boxes.len() { + for j in (i+1)..self.boxes.len() { + connections.push((self.boxes[i].dst(self.boxes[j]), (i, j))); + } + } + connections.sort_by(|a, b| a.0.cmp(&b.0)); + + let mut connections: Vec<(usize, usize)> = connections.into_iter() + .take(n_shortest) + .map(|(_, coord)| coord) + .collect(); + connections.sort(); + + let mut circuits: Vec> = Vec::new(); + connections.iter() + .for_each(|(b1, b2)| { + if let Some(i) = circuits.iter().position(|s| s.contains(b1)) { + if let Some(j) = circuits.iter().position(|s| s.contains(b2)) { + circuits.push( circuits[i].union(&circuits[j]).map(|v| *v).collect() ); + circuits.remove(i.max(j)); + if i != j { + circuits.remove(i.min(j)); + } + } else { + circuits[i].insert(*b2); + } + } else if let Some(i) = circuits.iter().position(|s| s.contains(b2)) { + if let Some(j) = circuits.iter().position(|s| s.contains(b1)) { + circuits.push( circuits[i].union(&circuits[j]).map(|v| *v).collect() ); + circuits.remove(i.max(j)); + if i != j { + circuits.remove(i.min(j)); + } + } else { + circuits[i].insert(*b1); + } + } else { + let mut s: HashSet = HashSet::new(); + s.insert(*b1); + s.insert(*b2); + circuits.push(s); + } + circuits.sort_by(|a, b| b.len().cmp(&a.len())); + // si b1 est dans un set de circuits + // - si b2 est dans un set de circuits + // -> relier les sets + // - sinon ajouter b2 au set + // si b2 est déjà dans un set de circuits + // - si b1 est dans un set de circuits + // -> relier les sets + // - sinon ajouter b1 au set + // sinon ajouter set (b1, b2) + }); + let mut circuits: Vec = circuits.iter().map(|set| set.len()).collect(); + circuits.sort_by(|a, b| b.cmp(a)); + circuits.iter().take(3).product() + } +} + +pub fn run(input: &str) -> Result<(), Box> { + let p = Puzzle::new(input); + println!("part1: {}", p.part1(1000)); + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + static TEST_INPUT: &str = "\ +162,817,812 +57,618,57 +906,360,560 +592,479,940 +352,342,300 +466,668,158 +542,29,236 +431,825,988 +739,650,466 +52,470,668 +216,146,977 +819,987,18 +117,168,530 +805,96,715 +346,949,466 +970,615,88 +941,993,340 +862,61,35 +984,92,344 +425,690,689 +"; + + #[test] + fn test_part1() { + assert_eq!(40, Puzzle::new(TEST_INPUT).part1(10)); + } +} diff --git a/src/main.rs b/src/main.rs index 8cb86b2..cbdd455 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ pub mod day04; pub mod day05; pub mod day06; pub mod day07; +pub mod day08; fn main() { let args: Vec = env::args().collect(); @@ -33,6 +34,7 @@ fn run(day: &str, input_file: &str) -> Result<(), Box> { "day05" => day05::run(&input)?, "day06" => day06::run(&input)?, "day07" => day07::run(&input)?, + "day08" => day08::run(&input)?, _ => return Err(format!("unknown or unimplemented day \"{day}\"").into()), } Ok(())