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
90
91
92
93
94
95
96
97
98
99
100
|
use regex::Regex;
use std::collections::HashMap;
static DAY: u8 = 14;
fn main() {
let input = advent::read_lines(DAY);
println!("{DAY}a: {}", safety_factor(&input, Position { x: 101, y: 103 }));
println!("{DAY}b: {}", 0);
}
struct Position {
x: isize,
y: isize,
}
struct Robot {
pos: Position,
velocity: Position,
}
impl Robot {
fn new(input: &str) -> Robot {
let re = Regex::new(r"p=([0-9]+),([0-9]+) v=([-0-9]+),([-0-9]+)").unwrap();
let caps = re.captures(input).unwrap();
let x = caps.get(1).unwrap().as_str().parse::<isize>().unwrap();
let y = caps.get(2).unwrap().as_str().parse::<isize>().unwrap();
let dx = caps.get(3).unwrap().as_str().parse::<isize>().unwrap();
let dy = caps.get(4).unwrap().as_str().parse::<isize>().unwrap();
Robot {
pos: Position { x, y },
velocity: Position { x: dx, y: dy },
}
}
fn travel(&mut self, area: &Position) {
self.pos.x = (self.pos.x + self.velocity.x + area.x) % area.x;
self.pos.y = (self.pos.y + self.velocity.y + area.y) % area.y;
}
fn quadrant(&self, area: &Position) -> u8 {
if self.pos.x < area.x / 2 && self.pos.y < area.y / 2 {
1
} else if self.pos.x < area.x / 2 && self.pos.y > area.y / 2 {
2
} else if self.pos.x > area.x / 2 && self.pos.y < area.y / 2 {
3
} else if self.pos.x > area.x / 2 && self.pos.y > area.y / 2 {
4
} else {
0
}
}
}
fn safety_factor(input: &[String], area: Position) -> u32 {
let mut robots = input.iter()
.map(|line| Robot::new(line))
.collect::<Vec<_>>();
for _ in 0 .. 100 {
for robot in robots.iter_mut() {
robot.travel(&area);
}
}
let mut quadrants = HashMap::new();
for robot in &robots {
let quadrant = robot.quadrant(&area);
if quadrant != 0 {
let entry = quadrants.entry(quadrant).or_insert(0);
*entry += 1;
}
}
quadrants.values().product()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
let input = [
"p=0,4 v=3,-3",
"p=6,3 v=-1,-3",
"p=10,3 v=-1,2",
"p=2,0 v=2,-1",
"p=0,0 v=1,3",
"p=3,0 v=-2,-2",
"p=7,6 v=-1,-3",
"p=3,0 v=-1,-2",
"p=9,3 v=2,3",
"p=7,3 v=-1,2",
"p=2,4 v=2,-3",
"p=9,5 v=-3,-3",
].iter().map(|&x| String::from(x)).collect::<Vec<_>>();
assert_eq!(safety_factor(&input, Position { x: 11, y: 7}), 12);
}
}
|