summaryrefslogtreecommitdiff
path: root/2024_rust/src/bin/day14.rs
diff options
context:
space:
mode:
Diffstat (limited to '2024_rust/src/bin/day14.rs')
-rw-r--r--2024_rust/src/bin/day14.rs131
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);
+}