Rust challenge 95/100 - aoc2024 day 14
Table of content
What is this
The rules of the game are explained in my original.
95th Challenge
Challenge
I finally got around to day 14 of advent of code.
Solution
Part 2 kept me quite busy. Because of the info about quadrants, I kept looking for symmetry. Until I just got annoyed and printed it to file and did a visual search with scrolling.
Scroll…scroll…scroll… Several minutes later
use pathfinding::prelude::{count_paths};
use std::io::Write;
#[derive(Debug, Clone, PartialOrd, PartialEq, Ord, Eq)]
struct Pos(u32, u32);
#[derive(Debug, Clone)]
struct Velocity(i32, i32);
#[derive(Debug, Clone)]
struct Robot {
pos: Pos,
vel: Velocity,
}
enum Quadrant {
TopRight,
TopLeft,
BottomRight,
BottomLeft,
None,
}
impl Robot {
fn next(&mut self, max_pos: &Pos) {
let max_x = max_pos.0 as i32 + 1;
let max_y = max_pos.1 as i32 + 1;
let new_x = (self.pos.0 as i32 + self.vel.0 as i32).rem_euclid(max_x) as u32;
let new_y = (self.pos.1 as i32 + self.vel.1 as i32).rem_euclid(max_y) as u32;
self.pos = Pos(new_x, new_y);
}
}
impl Pos {
fn get_quadrant(&self, max_pos: &Pos) -> Quadrant {
if self.0 > max_pos.0 / 2 && self.1 > max_pos.1 / 2 {
Quadrant::TopRight
} else if self.0 < max_pos.0 / 2 && self.1 > max_pos.1 / 2 {
Quadrant::TopLeft
} else if self.0 > max_pos.0 / 2 && self.1 < max_pos.1 / 2 {
Quadrant::BottomRight
} else if self.0 < max_pos.0 / 2 && self.1 < max_pos.1 / 2 {
Quadrant::BottomLeft
} else {
Quadrant::None
}
}
}
fn print_bots_to_file(time:i32,bots: &[Robot], max_pos: &Pos, file_name: &str) {
let mut grid = vec![vec!['.'; max_pos.0 as usize + 1]; max_pos.1 as usize + 1];
for bot in bots {
grid[bot.pos.1 as usize][bot.pos.0 as usize] = '#';
}
let mut file = std::fs::OpenOptions::new()
.append(true)
.create(true)
.open(file_name)
.unwrap();
writeln!(file, "{}", time).unwrap();
for row in grid {
writeln!(file, "{}", row.iter().collect::<String>()).unwrap();
}
}
fn main() {
let input = include_str!("input.txt");
let mut bots = input
.lines()
.map(|line| {
let mut parts = line.split(|c| c == '=' || c == ',' || c == ' ');
let x = parts.nth(1).unwrap().parse().unwrap();
let y = parts.next().unwrap().parse().unwrap();
let vx = parts.nth(1).unwrap().parse().unwrap();
let vy = parts.next().unwrap().parse().unwrap();
Robot {
pos: Pos(x, y),
vel: Velocity(vx, vy),
}
})
.collect::<Vec<_>>();
let simulation_time = 10_000;
let max_pos = &Pos(100, 102);
for i in 0..simulation_time {
for bot in &mut bots {
bot.next(max_pos);
}
let quadrant_counts = bots.iter().fold([0; 4], |mut counts, bot| {
match bot.pos.get_quadrant(max_pos) {
Quadrant::TopLeft => counts[0] += 1,
Quadrant::TopRight => counts[1] += 1,
Quadrant::BottomRight => counts[2] += 1,
Quadrant::BottomLeft => counts[3] += 1,
Quadrant::None => (),
}
counts
});
if i == 99 {
let quandrant_product = quadrant_counts.iter().fold(1, |acc, &count| acc * count);
println!("Quadrant product: {}", quandrant_product);
}
println!("Time: {}", i);
print_bots_to_file(i,&bots, max_pos, "images.txt");
}
}