From f9f79a03b575cfe94b73a602df0735b6d5236642 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Wed, 20 Dec 2017 07:30:45 +0200 Subject: Day 20: Colliding points in 3D --- src/bin/day_20.rs | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 25 ++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 src/bin/day_20.rs (limited to 'src') diff --git a/src/bin/day_20.rs b/src/bin/day_20.rs new file mode 100644 index 0000000..f528675 --- /dev/null +++ b/src/bin/day_20.rs @@ -0,0 +1,89 @@ +extern crate advent_of_code_2017; +use advent_of_code_2017::*; + +extern crate regex; +use regex::Regex; + +#[macro_use] +extern crate lazy_static; + +use std::str::FromStr; + +fn main() { + let args = AdventArgs::init(); + + let mut particles: Vec = args.input.iter() + .map(|line| line.parse().unwrap()) + .collect(); + + // I took eventually to be after a largish number. Seemed to work + // out, but I'm sure there is a more mathematical way to work it + // out. + for _ in 0..1000 { + particles = particles.iter().map(|p| p.step()).collect(); + if args.part == 2 { + let before_collisions = particles.clone(); + particles.retain(|p| { + before_collisions.iter().filter(|p2| p2.position == p.position).count() == 1 + }); + } + } + + if args.part == 1 { + let (closest, _) = particles.iter().enumerate().min_by_key(|&(_, p)| p.position.manhattan_distance()).unwrap(); + println!("Closest to 0: {}", closest); + } else { + let remaining = particles.iter().count(); + println!("Remaining: {}", remaining); + } + +} + +#[derive(Debug, Clone)] +struct Particle { + position: Point3d, + velocity: Point3d, + acceleration: Point3d +} + + +impl Particle { + fn step(&self) -> Particle { + let v = self.velocity + self.acceleration; + Particle { + position: self.position + v, + velocity: v, + acceleration: self.acceleration + } + } +} + +impl FromStr for Particle { + type Err = String; + + fn from_str(s: &str) -> Result { + lazy_static!{ + static ref RE: Regex = Regex::new(r"p=<(-?\d+),(-?\d+),(-?\d+)>, v=<(-?\d+),(-?\d+),(-?\d+)>, a=<(-?\d+),(-?\d+),(-?\d+)>").unwrap(); + }; + + let caps = RE.captures(s).unwrap(); + Ok(Particle { + position: Point3d { + x: caps[1].parse().unwrap(), + y: caps[2].parse().unwrap(), + z: caps[3].parse().unwrap() + }, + velocity: Point3d { + x: caps[4].parse().unwrap(), + y: caps[5].parse().unwrap(), + z: caps[6].parse().unwrap() + }, + acceleration: Point3d { + x: caps[7].parse().unwrap(), + y: caps[8].parse().unwrap(), + z: caps[9].parse().unwrap() + } + }) + } +} + diff --git a/src/lib.rs b/src/lib.rs index 452e67a..53d7d20 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -151,6 +151,31 @@ impl Direction { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct Point3d { + pub x: i32, + pub y: i32, + pub z: i32 +} + +impl std::ops::Add for Point3d { + type Output = Point3d; + + fn add(self, other: Point3d) -> Point3d { + Point3d { + x: self.x + other.x, + y: self.y + other.y, + z: self.z + other.z + } + } + +} + +impl Point3d { + pub fn manhattan_distance(&self) -> i32 { + self.x.abs() + self.y.abs() + self.z.abs() + } +} pub fn knot_hash(input: &String) -> String { let suffix: [usize; 5] = [17, 31, 73, 47, 23]; -- cgit v1.2.3