// [nix-shell:~/projects/sandbox/advent]$ cargo run --bin 12 // Compiling advent v0.1.0 (/home/orbekk/projects/sandbox/advent) // Finished dev [unoptimized + debuginfo] target(s) in 0.40s // Running `target/debug/12` // After 10 steps: // pos=, vel= // pos=, vel= // pos=, vel= // pos=, vel= // // energy=179 // // After 1000 steps: // pos=, vel= // pos=, vel= // pos=, vel= // pos=, vel= // // energy=14645 use std::fmt; #[derive(Debug)] struct Moon { position: (i64, i64, i64), velocity: (i64, i64, i64), } fn sign(x: i64) -> i64 { if x < 0 { -1 } else if x > 0 { 1 } else { 0 } } impl Moon { fn step(&self, moons: &Vec) -> Moon { let (x, y, z) = self.position; let (mut gx, mut gy, mut gz) = self.velocity; for moon in moons { let (ox, oy, oz) = moon.position; gx += sign(ox - x); gy += sign(oy - y); gz += sign(oz - z); } let position = (x + gx, y + gy, z + gz); Moon { position: position, velocity: (gx, gy, gz) } } fn energy(&self) -> i64 { let (x, y, z) = self.position; let (p, q, r) = self.velocity; (x.abs() + y.abs() + z.abs()) * (p.abs() + q.abs() + r.abs()) } } fn make_moon(x: i64, y: i64, z: i64) -> Moon { Moon { position: (x, y, z), velocity: (0, 0, 0) } } impl fmt::Display for Moon { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let (x, y, z) = self.position; let (p, q, r) = self.velocity; write!(f, "pos=, vel=", x, y, z, p, q, r) } } #[derive(Debug)] struct Moons(Vec); impl Moons { fn step(&self) -> Moons { Moons(self.0.iter().map(|m| m.step(&self.0)).collect()) } fn energy(&self) -> i64 { self.0.iter().map(|m| m.energy()).sum() } } impl fmt::Display for Moons { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { for moon in &self.0 { moon.fmt(f)?; write!(f, "\n")?; } Ok(()) } } fn run_steps(mut m: Moons, steps: i64, debug: bool) { for i in 0..steps { if debug { println!("After {} steps:", i); println!("{}", m); } m = m.step() } println!("After {} steps:", steps); println!("{}", m); println!("energy={:3}", m.energy()) } fn main() { let _ex1 = Moons(vec!( make_moon(-1, 0, 2), make_moon(2, -10, -7), make_moon(4, -8, 8), make_moon(3, 5, -1), )); let _ex2 = Moons(vec!( make_moon(-8, -10, 0), make_moon(5, 5, 10), make_moon(2, -7, 3), make_moon(9, -8, -3), )); run_steps(_ex1, 10, false); println!(); run_steps(_ex2, 1000, false); }