day12 task 2
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
mod tasks;
|
||||
|
||||
fn main() {
|
||||
tasks::day14::run();
|
||||
tasks::day12::run();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use num_integer::Integer;
|
||||
use regex::Regex;
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -14,10 +15,6 @@ pub fn run() {
|
||||
Point { x, y, z }
|
||||
})
|
||||
.collect();
|
||||
task1(input.clone());
|
||||
}
|
||||
|
||||
fn task1(input: Vec<Point>) {
|
||||
let moons: Vec<_> = input
|
||||
.into_iter()
|
||||
.map(|pos| Moon {
|
||||
@@ -25,42 +22,84 @@ fn task1(input: Vec<Point>) {
|
||||
vel: Point::new(0, 0, 0),
|
||||
})
|
||||
.collect();
|
||||
let finals = (0..1000).fold(moons, |moons, _run| {
|
||||
let gravities: Vec<Point> = moons
|
||||
.iter()
|
||||
.map(|base| {
|
||||
moons.iter().fold(Point::new(0, 0, 0), |grav, other_moon| {
|
||||
grav.add(base.pos.gravity(other_moon.pos))
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
let moons = moons
|
||||
.into_iter()
|
||||
.zip(gravities.into_iter())
|
||||
.map(|(mut moon, grav)| {
|
||||
moon.vel = moon.vel.add(grav);
|
||||
moon.pos = moon.pos.add(moon.vel);
|
||||
moon
|
||||
})
|
||||
.collect();
|
||||
//println!("{}: {:?}", run, moons);
|
||||
moons
|
||||
});
|
||||
task1(moons.clone());
|
||||
task2(moons.clone());
|
||||
}
|
||||
|
||||
fn task1(moons: Vec<Moon>) {
|
||||
let finals = (0..1000).fold(moons, |moons, _run| step(moons));
|
||||
let energy: i32 = finals
|
||||
.iter()
|
||||
.map(|moon| moon.pos.energy() * moon.vel.energy())
|
||||
.sum();
|
||||
println!("Task 1: sum of energy is {}", energy);
|
||||
//392 too low
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
fn task2(moons: Vec<Moon>) {
|
||||
let xstart: Vec<_> = moons.iter().map(|it| [it.pos.x, it.vel.x]).collect();
|
||||
let ystart: Vec<_> = moons.iter().map(|it| [it.pos.y, it.vel.y]).collect();
|
||||
let zstart: Vec<_> = moons.iter().map(|it| [it.pos.z, it.vel.z]).collect();
|
||||
let result = (1 as usize..)
|
||||
.scan((None, None, None, moons), |(dx, dy, dz, moons), run| {
|
||||
let mut new_moons = step(moons.clone());
|
||||
moons.clear();
|
||||
moons.append(&mut new_moons);
|
||||
|
||||
let xv: Vec<_> = moons.iter().map(|it| [it.pos.x, it.vel.x]).collect();
|
||||
let yv: Vec<_> = moons.iter().map(|it| [it.pos.y, it.vel.y]).collect();
|
||||
let zv: Vec<_> = moons.iter().map(|it| [it.pos.z, it.vel.z]).collect();
|
||||
if *dx == None && xv == xstart {
|
||||
*dx = Some(run);
|
||||
}
|
||||
if *dy == None && yv == ystart {
|
||||
*dy = Some(run);
|
||||
}
|
||||
if *dz == None && zv == zstart {
|
||||
*dz = Some(run);
|
||||
}
|
||||
if dx.is_some() && dy.is_some() && dz.is_some() {
|
||||
Some(Some((dx.unwrap(), dy.unwrap(), dz.unwrap())))
|
||||
} else {
|
||||
Some(None)
|
||||
}
|
||||
})
|
||||
.find(|bla| bla.is_some());
|
||||
if let Some(Some((x, y, z))) = result {
|
||||
println!(
|
||||
"Task 2: {:?} until a visited state is reached again",
|
||||
x.lcm(&y.lcm(&z))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn step(moons: Vec<Moon>) -> Vec<Moon> {
|
||||
let gravities: Vec<Point> = moons
|
||||
.iter()
|
||||
.map(|base| {
|
||||
moons.iter().fold(Point::new(0, 0, 0), |grav, other_moon| {
|
||||
grav.add(base.pos.gravity(other_moon.pos))
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
let moons = moons
|
||||
.into_iter()
|
||||
.zip(gravities.into_iter())
|
||||
.map(|(mut moon, grav)| {
|
||||
moon.vel = moon.vel.add(grav);
|
||||
moon.pos = moon.pos.add(moon.vel);
|
||||
moon
|
||||
})
|
||||
.collect();
|
||||
moons
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
struct Moon {
|
||||
pos: Point,
|
||||
vel: Point,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
struct Point {
|
||||
x: i32,
|
||||
y: i32,
|
||||
|
||||
Reference in New Issue
Block a user