From e8b911fac0013e1d0fe71824ba929bdb85783e39 Mon Sep 17 00:00:00 2001 From: Johannes Date: Sun, 15 Dec 2019 11:46:40 +0100 Subject: [PATCH] day12 task 2 --- Cargo.lock | 26 +++++++++++++ Cargo.toml | 1 + src/main.rs | 2 +- src/tasks/day12.rs | 95 ++++++++++++++++++++++++++++++++-------------- 4 files changed, 95 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ed1afa..ceffab9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,15 @@ name = "aoc_2019" version = "0.1.0" dependencies = [ "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "either" version = "1.5.3" @@ -39,6 +45,23 @@ name = "memchr" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "num-integer" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "regex" version = "1.3.1" @@ -65,10 +88,13 @@ dependencies = [ [metadata] "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" +"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" +"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" +"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4" "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" diff --git a/Cargo.toml b/Cargo.toml index 2fa0793..0620ed1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,4 @@ edition = "2018" [dependencies] itertools = "0.8.2" regex = "1.3.1" +num-integer = "0.1" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 6415156..d075db8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ mod tasks; fn main() { - tasks::day14::run(); + tasks::day12::run(); } diff --git a/src/tasks/day12.rs b/src/tasks/day12.rs index edcb53a..400531d 100644 --- a/src/tasks/day12.rs +++ b/src/tasks/day12.rs @@ -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) { let moons: Vec<_> = input .into_iter() .map(|pos| Moon { @@ -25,42 +22,84 @@ fn task1(input: Vec) { vel: Point::new(0, 0, 0), }) .collect(); - let finals = (0..1000).fold(moons, |moons, _run| { - let gravities: Vec = 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) { + 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) { + 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) -> Vec { + let gravities: Vec = 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,