summaryrefslogtreecommitdiff
path: root/2017/src/bin/day_20.rs
blob: f5286752034fd76691a4d02bb4c63c1fcf3fe31d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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<Particle> = 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<Self, Self::Err> {
        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()
            }
        })
    }
}