2024-12-15 13:22:03 +01:00
|
|
|
use advent_of_code::{
|
|
|
|
strings::{convert_to_array, parsenumber},
|
|
|
|
Kartesian, Velocity, KD,
|
|
|
|
};
|
2024-12-19 17:12:39 +01:00
|
|
|
use advent_of_code_macros::include_aoc;
|
2024-12-15 13:22:03 +01:00
|
|
|
|
2024-12-19 17:12:39 +01:00
|
|
|
include_aoc!(2024, 14);
|
2024-12-15 13:22:03 +01:00
|
|
|
|
|
|
|
fn parse_robot(line: &str) -> (Kartesian<u32>, Velocity<u32>) {
|
|
|
|
let mut dir = KD::None;
|
|
|
|
let mut x = 0;
|
|
|
|
let mut y = 0;
|
|
|
|
let mut position = Kartesian::default();
|
|
|
|
for part in line.splitn(2, ' ') {
|
|
|
|
match part.get(0..2).unwrap_or("") {
|
|
|
|
"p=" => {
|
|
|
|
let (y, x) = part.get(2..).unwrap().split_once(',').unwrap();
|
|
|
|
position.x = parsenumber(x);
|
|
|
|
position.y = parsenumber(y);
|
|
|
|
},
|
|
|
|
"v=" => {
|
|
|
|
let (ys, xs) = part.get(2..).unwrap().split_once(',').unwrap();
|
|
|
|
x = parsenumber(xs);
|
|
|
|
y = parsenumber(ys);
|
|
|
|
dir = if xs.get(0..1).unwrap() == "-" && x != 0 {
|
|
|
|
dir.up()
|
|
|
|
} else if x > 0 {
|
|
|
|
dir.down()
|
|
|
|
} else {
|
|
|
|
dir
|
|
|
|
};
|
|
|
|
dir = if ys.get(0..1).unwrap() == "-" && y != 0 {
|
|
|
|
dir.left()
|
|
|
|
} else if x > 0 {
|
|
|
|
dir.right()
|
|
|
|
} else {
|
|
|
|
dir
|
|
|
|
};
|
|
|
|
},
|
|
|
|
_ => {},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
(position, Velocity::new(x, y, dir))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn get_end_start(v: u32) -> (u32, u32) {
|
|
|
|
match v % 2 {
|
|
|
|
0 => (v / 2, v / 2),
|
|
|
|
1 => ((v - 1) / 2 - 1, (v + 1) / 2),
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn calc_safety(coords: Vec<Kartesian<u32>>, space: Kartesian<u32>) -> (u32, u32, u32, u32) {
|
|
|
|
let mut robots = (0, 0, 0, 0);
|
|
|
|
let (x_end, x_start) = get_end_start(space.x);
|
|
|
|
let (y_end, y_start) = get_end_start(space.y);
|
|
|
|
for robot in coords {
|
|
|
|
if robot.x <= x_end && robot.y <= y_end {
|
|
|
|
robots.0 += 1;
|
|
|
|
} else if robot.x <= x_end && robot.y >= y_start {
|
|
|
|
robots.1 += 1
|
|
|
|
} else if robot.x >= x_start && robot.y <= y_end {
|
|
|
|
robots.2 += 1
|
|
|
|
} else if robot.x >= x_start && robot.y >= y_start {
|
|
|
|
robots.3 += 1
|
|
|
|
} else {
|
|
|
|
println!("Robot outside of quarts {}:", robot);
|
|
|
|
println!("1. {}..={}:{}..={}", 0, x_end, 0, y_end);
|
|
|
|
println!("2. {}..={}:{}..={}", 0, x_end, y_start, space.y - 1);
|
|
|
|
println!("3. {}..={}:{}..={}", x_start, space.x - 1, 0, y_end);
|
|
|
|
println!("4. {}..={}:{}..={}", x_start, space.x - 1, y_start, space.y - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
println!("Robot in quarts: {}, {}, {}, {}", robots.0, robots.1, robots.2, robots.3);
|
|
|
|
robots
|
|
|
|
}
|
|
|
|
|
|
|
|
fn calc_final(r: (u32, u32, u32, u32)) -> u32 {
|
|
|
|
r.0 * r.1 * r.2 * r.3
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
const SPACE: Kartesian<u32> = Kartesian::new(103, 101);
|
|
|
|
|
|
|
|
let mut target_coords = Vec::new();
|
|
|
|
let robots = convert_to_array::<_, _, '\n'>(DATA, parse_robot);
|
|
|
|
for (mut position, velocity) in robots {
|
|
|
|
for _i in 0..100 {
|
|
|
|
position = position.wrapping_move_velocity(velocity, SPACE);
|
|
|
|
}
|
|
|
|
target_coords.push(position);
|
|
|
|
}
|
|
|
|
println!("{:?}", target_coords);
|
|
|
|
println!("Safety Factor: {}", calc_final(calc_safety(target_coords, SPACE)));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_start_end() {
|
|
|
|
assert_eq!(get_end_start(7), (2, 4))
|
|
|
|
}
|
|
|
|
#[test]
|
|
|
|
fn test_safety() {
|
|
|
|
let positions = vec![
|
2024-12-16 22:12:30 +01:00
|
|
|
Kartesian {
|
|
|
|
x: 5,
|
|
|
|
y: 3,
|
|
|
|
},
|
|
|
|
Kartesian {
|
|
|
|
x: 4,
|
|
|
|
y: 5,
|
|
|
|
},
|
|
|
|
Kartesian {
|
|
|
|
x: 0,
|
|
|
|
y: 9,
|
|
|
|
},
|
|
|
|
Kartesian {
|
|
|
|
x: 5,
|
|
|
|
y: 4,
|
|
|
|
},
|
|
|
|
Kartesian {
|
|
|
|
x: 6,
|
|
|
|
y: 1,
|
|
|
|
},
|
|
|
|
Kartesian {
|
|
|
|
x: 3,
|
|
|
|
y: 1,
|
|
|
|
},
|
|
|
|
Kartesian {
|
|
|
|
x: 0,
|
|
|
|
y: 6,
|
|
|
|
},
|
|
|
|
Kartesian {
|
|
|
|
x: 3,
|
|
|
|
y: 2,
|
|
|
|
},
|
|
|
|
Kartesian {
|
|
|
|
x: 2,
|
|
|
|
y: 0,
|
|
|
|
},
|
|
|
|
Kartesian {
|
|
|
|
x: 0,
|
|
|
|
y: 6,
|
|
|
|
},
|
|
|
|
Kartesian {
|
|
|
|
x: 5,
|
|
|
|
y: 4,
|
|
|
|
},
|
|
|
|
Kartesian {
|
|
|
|
x: 6,
|
|
|
|
y: 6,
|
|
|
|
},
|
2024-12-15 13:22:03 +01:00
|
|
|
];
|
|
|
|
assert_eq!(calc_safety(positions, Kartesian::new(7, 11)), (1, 3, 4, 1));
|
|
|
|
}
|
|
|
|
}
|