diff --git a/Cargo.lock b/Cargo.lock index 2056020..8e4b96e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,7 @@ name = "aoc_2018" version = "0.1.0" dependencies = [ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "gcd 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -35,6 +36,11 @@ name = "either" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "gcd" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "itertools" version = "0.7.11" @@ -158,6 +164,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" +"checksum gcd 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0896cb73353671dbe2b17312c97b55b7032831d28c809c703bece4a392b1df3a" "checksum itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" "checksum libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)" = "10923947f84a519a45c8fefb7dd1b3e8c08747993381adee176d7a82b4195311" diff --git a/Cargo.toml b/Cargo.toml index b3fd792..8630dad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,4 @@ edition = "2018" regex = "1.1.0" chrono = "0.4.6" itertools = "0.7.11" +gcd = "1.1.0" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 44c35ec..fc32bc4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ fn main() { - aoc_2018::tasks::day23::task1(); - // aoc_2018::tasks::day15::task2(); + // aoc_2018::tasks::day23::task1(); + aoc_2018::tasks::day23::task2(); } diff --git a/src/tasks/day23.rs b/src/tasks/day23.rs index a57205c..5626516 100644 --- a/src/tasks/day23.rs +++ b/src/tasks/day23.rs @@ -30,6 +30,70 @@ pub fn task1() { println!("There are {} bots in range of the big bot.", bots_in_range); } +pub fn task2() { + let input = utils::read_file("input/day23.txt"); + let regex = + Regex::new(r"^pos=<(?P-?\d+),(?P-?\d+),(?P-?\d+)>, r=(?P\d+)$").unwrap(); + let bots: Vec = input + .lines() + .map(|line| { + let m = regex.captures(line).unwrap(); + let x = m["x"].parse::().unwrap(); + let y = m["y"].parse::().unwrap(); + let z = m["z"].parse::().unwrap(); + let range = m["range"].parse::().unwrap(); + + Bot { x, y, z, range } + }) + .collect(); + + // let r_min = bots.iter().min_by_key(|it| it.range).unwrap().range; + // let r_max = bots.iter().max_by_key(|it| it.range).unwrap().range; + // println!("Radius min max: {}/{}", r_min, r_max); + // let x_min = bots.iter().min_by_key(|it| it.x).unwrap().x; + // let x_max = bots.iter().max_by_key(|it| it.x).unwrap().x; + // println!("X range: {}", x_max - x_min); + // let y_min = bots.iter().min_by_key(|it| it.y).unwrap().y; + // let y_max = bots.iter().max_by_key(|it| it.y).unwrap().y; + // println!("Y range: {}", y_max - y_min); + // let z_min = bots.iter().min_by_key(|it| it.z).unwrap().z; + // let z_max = bots.iter().max_by_key(|it| it.z).unwrap().z; + // println!("Z range: {}", z_max - z_min); + + let neighbor_counts: Vec<(Bot, usize)> = bots + .iter() + .flat_map(|bot| bot.corners()) + .map(|corner| { + let count = bots + .iter() + .filter(|bot| bot.distance(&corner) <= bot.range) + .count(); + (corner, count) + }) + .collect(); + + let max = neighbor_counts.iter().max_by_key(|it| it.1).unwrap().1; + + let start = Bot { + x: 0, + y: 0, + z: 0, + range: 0, + }; + let candidates = neighbor_counts.iter().filter(|it| it.1 == max).count(); + println!("{} points in range of {} bots", candidates, max); + let candidate = neighbor_counts + .iter() + .filter(|it| it.1 == max) + .min_by_key(|it| it.0.distance(&start)); + + println!( + "Corner with most bots in range: {:?}", + candidate.unwrap().0.distance(&start) + ); + // wrong: 37446460,43177892,57318660; 137943012; 102224079; +} + #[derive(Debug)] struct Bot { x: isize, @@ -42,4 +106,45 @@ impl Bot { fn distance(&self, other: &Self) -> usize { ((other.x - self.x).abs() + (other.y - self.y).abs() + (other.z - self.z).abs()) as usize } + + fn corners(&self) -> Vec { + vec![ + Bot { + x: self.x + self.range as isize, + y: self.y, + z: self.z, + range: 0, + }, + Bot { + x: self.x - self.range as isize, + y: self.y, + z: self.z, + range: 0, + }, + Bot { + x: self.x, + y: self.y + self.range as isize, + z: self.z, + range: 0, + }, + Bot { + x: self.x, + y: self.y - self.range as isize, + z: self.z, + range: 0, + }, + Bot { + x: self.x, + y: self.y, + z: self.z + self.range as isize, + range: 0, + }, + Bot { + x: self.x, + y: self.y, + z: self.z - self.range as isize, + range: 0, + }, + ] + } }