Skip to content

Commit d7f9107

Browse files
committed
Day 14
1 parent 15a04a5 commit d7f9107

File tree

3 files changed

+120
-2
lines changed

3 files changed

+120
-2
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
4141
| [Day 10](./src/bin/10.rs) | `96.9µs` | `97.3µs` |
4242
| [Day 11](./src/bin/11.rs) | `218.3µs` | `11.2ms` |
4343
| [Day 12](./src/bin/12.rs) | `3.0ms` | `2.8ms` |
44-
| [Day 13](./src/bin/13.rs) | `246.8µs` | `198.9µs` |
44+
| [Day 13](./src/bin/13.rs) | `248.3µs` | `204.6µs` |
45+
| [Day 14](./src/bin/14.rs) | `46.3µs` | `46.2ms` |
4546

46-
**Total: 193.77ms**
47+
**Total: 240.03ms**
4748
<!--- benchmarking table --->
4849

4950
---

data/examples/14.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
p=0,4 v=3,-3
2+
p=6,3 v=-1,-3
3+
p=10,3 v=-1,2
4+
p=2,0 v=2,-1
5+
p=0,0 v=1,3
6+
p=3,0 v=-2,-2
7+
p=7,6 v=-1,-3
8+
p=3,0 v=-1,-2
9+
p=9,3 v=2,3
10+
p=7,3 v=-1,2
11+
p=2,4 v=2,-3
12+
p=9,5 v=-3,-3

src/bin/14.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
use itertools::Itertools;
2+
3+
advent_of_code::solution!(14);
4+
5+
#[cfg(not(test))]
6+
const WIDTH: u8 = 101;
7+
#[cfg(not(test))]
8+
const HEIGHT: u8 = 103;
9+
10+
#[cfg(test)]
11+
const WIDTH: u8 = 11;
12+
#[cfg(test)]
13+
const HEIGHT: u8 = 7;
14+
15+
#[derive(Debug)]
16+
struct Robot {
17+
position: (isize, isize),
18+
velocity: (isize, isize),
19+
}
20+
21+
impl Robot {
22+
fn parse(input: &str) -> Robot {
23+
let pos_x = &input[input.find('=').unwrap() + 1..input.find(',').unwrap()];
24+
let pos_y = &input[input.find(',').unwrap() + 1..input.find(' ').unwrap()];
25+
26+
let vel_x = &input[input.rfind('=').unwrap() + 1..input.rfind(',').unwrap()];
27+
let vel_y = &input[input.rfind(',').unwrap() + 1..];
28+
29+
Robot {
30+
position: (pos_x.parse().unwrap(), pos_y.parse().unwrap()),
31+
velocity: (vel_x.parse().unwrap(), vel_y.parse().unwrap()),
32+
}
33+
}
34+
35+
fn simulate(&mut self, seconds: isize) {
36+
let (offset_x, offset_y) = (self.velocity.0 * seconds, self.velocity.1 * seconds);
37+
let new_position = (self.position.0 + offset_x, self.position.1 + offset_y);
38+
self.position = (new_position.0.rem_euclid(WIDTH as isize), new_position.1.rem_euclid(HEIGHT as isize));
39+
}
40+
41+
fn get_quadrant(&self) -> Option<u8> {
42+
let (center_column, center_row) = (WIDTH as isize / 2, HEIGHT as isize / 2);
43+
if self.position.0 < center_column && self.position.1 < center_row {
44+
Some(0)
45+
} else if self.position.0 > center_column && self.position.1 < center_row {
46+
Some(1)
47+
} else if self.position.0 < center_column && self.position.1 > center_row {
48+
Some(2)
49+
} else if self.position.0 > center_column && self.position.1 > center_row {
50+
Some(3)
51+
} else {
52+
None
53+
}
54+
}
55+
}
56+
57+
pub fn part_one(input: &str) -> Option<u32> {
58+
let mut quadrants = [0; 4];
59+
input.lines()
60+
.map(Robot::parse)
61+
.map(|mut robot| {
62+
robot.simulate(100);
63+
robot
64+
})
65+
.filter_map(|robot| robot.get_quadrant())
66+
.for_each(|quadrant| quadrants[quadrant as usize] += 1);
67+
Some(quadrants.iter().product())
68+
}
69+
70+
pub fn part_two(input: &str) -> Option<u32> {
71+
let (mut lowest_safety_factor, mut seconds_passed) = (u32::MAX, 0);
72+
let mut robots = input.lines().map(Robot::parse).collect_vec();
73+
for second in 1..=WIDTH as u16 * HEIGHT as u16 {
74+
let mut quadrants = [0; 4];
75+
robots.iter_mut()
76+
.map(|robot| {
77+
robot.simulate(1);
78+
robot
79+
})
80+
.filter_map(|robot| robot.get_quadrant())
81+
.for_each(|quadrant| quadrants[quadrant as usize] += 1);
82+
let safety_factor = quadrants.iter().product();
83+
if safety_factor < lowest_safety_factor {
84+
lowest_safety_factor = safety_factor;
85+
seconds_passed = second;
86+
}
87+
}
88+
Some(seconds_passed as u32)
89+
}
90+
91+
#[cfg(test)]
92+
mod tests {
93+
use super::*;
94+
95+
#[test]
96+
fn test_part_one() {
97+
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
98+
assert_eq!(result, Some(12));
99+
}
100+
101+
#[test]
102+
fn test_part_two() {
103+
// Cannot test part two
104+
}
105+
}

0 commit comments

Comments
 (0)