summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReiner Herrmann <reiner@reiner-h.de>2024-12-17 12:25:48 +0100
committerReiner Herrmann <reiner@reiner-h.de>2024-12-17 12:25:48 +0100
commit47b2f7a5e373d746dfa776e0c495b90d500a5cce (patch)
treed8844fd30e1f4c49af500c9aa7d4e95dc24b2c9e
parentd3e4b816edc2758a7773406aed6fbefdce8f7f9c (diff)
day14 solution 2
-rw-r--r--src/bin/day14.rs88
1 files changed, 73 insertions, 15 deletions
diff --git a/src/bin/day14.rs b/src/bin/day14.rs
index 531e1b4..31da4c4 100644
--- a/src/bin/day14.rs
+++ b/src/bin/day14.rs
@@ -1,14 +1,15 @@
use regex::Regex;
-use std::collections::HashMap;
+use std::collections::{HashMap, HashSet};
static DAY: u8 = 14;
fn main() {
let input = advent::read_lines(DAY);
println!("{DAY}a: {}", safety_factor(&input, Position { x: 101, y: 103 }));
- println!("{DAY}b: {}", 0);
+ println!("{DAY}b: {}", find_tree(&input, Position { x: 101, y: 103 }));
}
+#[derive(Eq, PartialEq, Hash, Clone, Copy)]
struct Position {
x: isize,
y: isize,
@@ -54,25 +55,82 @@ impl Robot {
}
}
+struct RobotMap {
+ robots: Vec<Robot>,
+ area: Position,
+}
+
+impl RobotMap {
+ fn new(input: &[String], area: Position) -> RobotMap {
+ let robots = input.iter()
+ .map(|line| Robot::new(line))
+ .collect::<Vec<_>>();
+ RobotMap { robots, area }
+ }
+
+ fn tick(&mut self) {
+ for robot in self.robots.iter_mut() {
+ robot.travel(&self.area);
+ }
+ }
+
+ fn safety_factor(&self) -> u32 {
+ let mut quadrants = HashMap::new();
+ for robot in &self.robots {
+ let quadrant = robot.quadrant(&self.area);
+ if quadrant != 0 {
+ let entry = quadrants.entry(quadrant).or_insert(0);
+ *entry += 1;
+ }
+ }
+ quadrants.values().product()
+ }
+
+ fn to_text(&self) -> String {
+ let mut map = String::new();
+
+ let positions = self.robots.iter()
+ .map(|robot| robot.pos)
+ .collect::<HashSet<_>>();
+ for y in 0 .. self.area.y {
+ for x in 0 .. self.area.x {
+ if positions.contains(&Position { x, y }) {
+ map += "*";
+ } else {
+ map += ".";
+ }
+ }
+ map += "\n";
+ }
+ map
+ }
+
+ fn draw(&self) {
+ println!("{}", self.to_text());
+ }
+}
+
fn safety_factor(input: &[String], area: Position) -> u32 {
- let mut robots = input.iter()
- .map(|line| Robot::new(line))
- .collect::<Vec<_>>();
+ let mut robotmap = RobotMap::new(input, area);
+
for _ in 0 .. 100 {
- for robot in robots.iter_mut() {
- robot.travel(&area);
- }
+ robotmap.tick();
}
+ robotmap.safety_factor()
+}
- let mut quadrants = HashMap::new();
- for robot in &robots {
- let quadrant = robot.quadrant(&area);
- if quadrant != 0 {
- let entry = quadrants.entry(quadrant).or_insert(0);
- *entry += 1;
+fn find_tree(input: &[String], area: Position) -> u32 {
+ let mut robotmap = RobotMap::new(input, area);
+ let mut i = 0;
+ loop {
+ robotmap.tick();
+ i += 1;
+ /* output likely contains a lot of robots closely together */
+ if robotmap.to_text().contains("*********") {
+ robotmap.draw();
+ return i;
}
}
- quadrants.values().product()
}
#[cfg(test)]