diff options
Diffstat (limited to '2024_rust/src/bin/day14.rs')
-rw-r--r-- | 2024_rust/src/bin/day14.rs | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/2024_rust/src/bin/day14.rs b/2024_rust/src/bin/day14.rs new file mode 100644 index 0000000..55f986b --- /dev/null +++ b/2024_rust/src/bin/day14.rs @@ -0,0 +1,131 @@ +use regex::Regex; +use std::collections::HashSet; + +fn cycle_add(u: u32, i: i32, limit: u32) -> u32 { + let sum: i32 = u as i32 + i; + let mut sum_u: u32 = if sum < 0 { sum + limit as i32 } else { sum } as u32; + while sum_u >= limit { + sum_u -= limit; + } + sum_u +} + +#[derive(Debug)] +struct Robot { + p: (u32, u32), + v: (i32, i32), +} + +impl Robot { + fn parse(input: &str) -> Vec<Self> { + let mut result: Vec<_> = vec![]; + let re = Regex::new(r"p=([0-9]+),([0-9]+) v=([0-9-]+),([0-9-]+)").unwrap(); + for (_, [px, py, vx, vy]) in re.captures_iter(input).map(|c| c.extract()) { + result.push(Robot { + p: (px.parse().unwrap(), py.parse().unwrap()), + v: (vx.parse().unwrap(), vy.parse().unwrap()), + }); + } + // println!("Result: {result:?}"); + result + } + + fn step(&mut self, (lx, ly): (u32, u32)) { + let p: &mut (u32, u32) = &mut self.p; + let v = self.v; + p.0 = cycle_add(p.0, v.0, lx); + p.1 = cycle_add(p.1, v.1, ly); + } +} + +struct Bathroom { + robots: Vec<Robot>, + limit: (u32, u32), +} + +impl Bathroom { + fn step(&mut self) { + for r in self.robots.iter_mut() { + r.step(self.limit); + } + } + + fn stepn(&mut self, seconds: u32) { + for _i in 0..seconds { + self.step(); + } + } + + fn quadrant(&self, Robot { p: (px, py), .. }: &Robot) -> Option<usize> { + let (lx, ly) = self.limit; + let (hx, hy) = (lx / 2, ly / 2); + if *px == hx || *py == hy { + None + } else { + Some(if *px < hx { 0 } else { 1 } + if *py < hy { 0 } else { 2 }) + } + } + + fn safety(&self) -> u32 { + let mut scores = [0; 4]; + for r in self.robots.iter() { + if let Some(q) = self.quadrant(r) { + scores[q] += 1; + } + } + scores.iter().product() + } + + fn show(&self) { + let positions: HashSet<(u32, u32)> = self.robots.iter().map(|r| r.p).collect(); + for i in 0..self.limit.1 { + for j in 0..self.limit.0 { + print!( + "{}", + if positions.contains(&(i, j)) { + "X" + } else { + "." + } + ); + } + println!(""); + } + } +} + +fn p1(input: &str) -> String { + let robots: Vec<Robot> = Robot::parse(input); + let mut bathroom: Bathroom = Bathroom { + robots, + limit: (101, 103), + }; + bathroom.stepn(100); + dbg!(&bathroom.robots); + + let result = bathroom.safety(); + result.to_string() +} + +// use std::thread::sleep; +// use std::time::Duration; + +fn p2(input: &str) -> String { + let robots: Vec<Robot> = Robot::parse(input); + let mut bathroom: Bathroom = Bathroom { + robots, + limit: (101, 103), + }; + bathroom.show(); + for i in 1.. { + println!("\n\nAfter {} seconds:", i); + bathroom.step(); + bathroom.show(); + // sleep(Duration::from_millis(200)); + } + unreachable!(); +} + +fn main() { + aoc2024::run_day("14", p1, p2); +} |