Untitled
unknown
rust
a year ago
3.2 kB
34
Indexable
const ORDERING: [Ordering; 2] = [Ordering::Less, Ordering::Greater];
pub fn solution(test: bool) -> ((usize, Duration), (usize, Duration)) {
let lines;
if test {
lines = include_str!("../../../AdventOfCodeInputs/problem_inputs_2024/day_14_test.txt");
} else {
lines = include_str!("../../../AdventOfCodeInputs/problem_inputs_2024/day_14.txt");
}
let room = Room::from_str(&lines);
(solve01(&room), solve02(&room))
}
fn solve01(room: &Room) -> (usize, Duration) {
let mut room = room.clone();
let now = Instant::now();
for _ in 0..100 {
room.step();
}
(room.calc_safety() as usize, now.elapsed())
}
fn solve02(room: &Room) -> (usize, Duration) {
let mut room = room.clone();
let now = Instant::now();
let step = (0..room.bounds.0 * room.bounds.1)
.map(|_| {
let safety = room.calc_safety();
room.step();
safety
})
.enumerate()
.min_by_key(|(step, factor)| *factor)
.unwrap();
(step.0 as usize, now.elapsed())
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Robot {
position: (isize, isize),
velocity: (isize, isize),
}
impl Robot {
fn from_str(s: &str) -> Self {
let mut s = s.split(' ');
let position = parse_vector(&mut s);
let velocity = parse_vector(&mut s);
Self { position, velocity }
}
fn step(&mut self, bounds: (isize, isize)) {
self.position.0 += self.velocity.0;
self.position.1 += self.velocity.1;
self.position.0 = self.position.0.rem_euclid(bounds.0 + 1);
self.position.1 = self.position.1.rem_euclid(bounds.1 + 1);
}
}
#[derive(Debug, Clone)]
struct Room {
robots: Vec<Robot>,
bounds: (isize, isize),
}
impl Room {
fn from_str(s: &str) -> Self {
let robots = s.lines().map(Robot::from_str).collect_vec();
let bounds = robots.iter().fold((0, 0), |acc, robot| {
(acc.0.max(robot.position.0), acc.1.max(robot.position.1))
});
Self { robots, bounds }
}
fn step(&mut self) {
for robot in &mut self.robots {
robot.step(self.bounds);
}
}
fn calc_safety(&self) -> usize {
let mut counts = [0; 4];
for (i, (order_x, order_y)) in ORDERING
.iter()
.cartesian_product(ORDERING.iter())
.enumerate()
{
counts[i] = self
.robots
.iter()
.filter(|robot| {
robot.position.0.cmp(&(self.bounds.0 / 2)) == *order_x
&& robot.position.1.cmp(&(self.bounds.1 / 2)) == *order_y
})
.count();
}
counts.iter().product()
}
fn check_if_tree(&self) -> bool {
self.robots
.iter()
.permutations(2)
.all(|r| r[0].velocity != r[1].velocity)
}
}
fn parse_vector(s: &mut std::str::Split<'_, char>) -> (isize, isize) {
let vector = s
.next()
.unwrap()
.split('=')
.nth(1)
.unwrap()
.split(',')
.map(|x| x.parse().unwrap())
.collect_tuple()
.unwrap();
vector
}Editor is loading...
Leave a Comment