From 7f09510a3169c13a4f1181ff24f978d42fcf58f5 Mon Sep 17 00:00:00 2001 From: Guillermo Ramos Date: Sat, 14 Dec 2024 17:27:23 +0100 Subject: 2024.14 --- 2024_rust/src/bin/day12.rs | 49 +++++++++-------- 2024_rust/src/bin/day14.rs | 131 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+), 23 deletions(-) create mode 100644 2024_rust/src/bin/day14.rs (limited to '2024_rust/src/bin') diff --git a/2024_rust/src/bin/day12.rs b/2024_rust/src/bin/day12.rs index 21868aa..4408980 100644 --- a/2024_rust/src/bin/day12.rs +++ b/2024_rust/src/bin/day12.rs @@ -1,9 +1,7 @@ use aoc2024::matrix; use std::collections::HashSet; -static PLUS_DELTAS: [(isize, isize); 4] = [ - (-1, 0), (0, -1), (0, 1), (1, 0) -]; +static PLUS_DELTAS: [(isize, isize); 4] = [(-1, 0), (0, -1), (0, 1), (1, 0)]; type Price = u32; type Matrix = matrix::Matrix; @@ -23,7 +21,7 @@ fn regions_price(m: &Matrix, version: u8) -> Price { for i in 0..m.limit.0 { for j in 0..m.limit.1 { let pos = (i, j); - if ! visited.contains(&pos) { + if !visited.contains(&pos) { let (price, pss) = region(m, pos, version); result += price; for p in pss { @@ -78,7 +76,10 @@ struct Lines { impl Lines { fn new() -> Self { - Lines { hs: vec![], vs: vec![] } + Lines { + hs: vec![], + vs: vec![], + } } fn from_pos(pos: matrix::Pos, in_region: &HashSet) -> Self { @@ -89,25 +90,21 @@ impl Lines { // println!(" Checking p {p:?}"); let p_u = (p.0 as usize, p.1 as usize); // println!(" Checking p_u {p_u:?}"); - if ! in_region.contains(&p_u) { + if !in_region.contains(&p_u) { if p.0 == pos.0 as isize { // println!(" PUSHING V ({} vs {}!", p.1, pos.1); - vs.push( - if p.1 < pos.1 as isize { - (true, pos) - } else { - (false, (pos.0, pos.1+1)) - } - ) + vs.push(if p.1 < pos.1 as isize { + (true, pos) + } else { + (false, (pos.0, pos.1 + 1)) + }) } else { // println!(" PUSHING H ({} vs {}!", p.0, pos.0); - hs.push( - if p.0 < pos.0 as isize { - (true, pos) - } else { - (false, (pos.0+1, pos.1)) - } - ) + hs.push(if p.0 < pos.0 as isize { + (true, pos) + } else { + (false, (pos.0 + 1, pos.1)) + }) } } } @@ -125,8 +122,15 @@ impl Lines { self.hs[..].sort(); self.vs[..].sort_by(|(d1, (x1, y1)), (d2, (x2, y2))| (d1, y1, x1).cmp(&(d2, y2, x2))); // println!("Sorted self: {self:?}"); - self.hs.chunk_by(|(d1, (x1, y1)), (d2, (x2, y2))| d1 == d2 && x1 == x2 && *y1 == y2-1).collect::>().len() as u32 + - self.vs.chunk_by(|(d1, (x1, y1)), (d2, (x2, y2))| d1 == d2 && y1 == y2 && *x1 == x2-1).collect::>().len() as u32 + self.hs + .chunk_by(|(d1, (x1, y1)), (d2, (x2, y2))| d1 == d2 && x1 == x2 && *y1 == y2 - 1) + .collect::>() + .len() as u32 + + self + .vs + .chunk_by(|(d1, (x1, y1)), (d2, (x2, y2))| d1 == d2 && y1 == y2 && *x1 == x2 - 1) + .collect::>() + .len() as u32 } } @@ -134,7 +138,6 @@ impl Lines { // xs.chunk_by(|().len() // } - fn region(m: &Matrix, pos: matrix::Pos, version: u8) -> (Price, HashSet) { match version { 1 => region_v1(m, pos), 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 { + 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, + 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 { + 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::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::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); +} -- cgit v1.2.3