116 lines
2.9 KiB
Rust
116 lines
2.9 KiB
Rust
use nom::{
|
|
bytes::complete::tag,
|
|
character::complete::{i64, multispace1},
|
|
multi::separated_list1,
|
|
sequence::{preceded, separated_pair},
|
|
IResult,
|
|
};
|
|
|
|
fn parse(input: &str) -> IResult<&str, Vec<((i64, i64), (i64, i64))>> {
|
|
let (input, result) = separated_list1(
|
|
multispace1,
|
|
separated_pair(
|
|
separated_pair(preceded(tag("p="), i64), tag(","), i64),
|
|
tag(" v="),
|
|
separated_pair(i64, tag(","), i64),
|
|
),
|
|
)(input)?;
|
|
|
|
Ok((input, result))
|
|
}
|
|
|
|
fn calc_pos(
|
|
start_pos: (i64, i64),
|
|
velocity: (i64, i64),
|
|
width: i64,
|
|
height: i64,
|
|
time: i64,
|
|
) -> (i64, i64) {
|
|
let x = (start_pos.0 + velocity.0 * time).rem_euclid(width);
|
|
let y = (start_pos.1 + velocity.1 * time).rem_euclid(height);
|
|
|
|
(x, y)
|
|
}
|
|
|
|
fn solve_1(input: &str, width: i64, height: i64) -> i64 {
|
|
let (_, result) = parse(input).unwrap();
|
|
|
|
let (mut q1, mut q2, mut q3, mut q4) = (0, 0, 0, 0);
|
|
for (x_end, y_end) in result
|
|
.into_iter()
|
|
.map(|(pos, vel)| calc_pos(pos, vel, width, height, 100))
|
|
{
|
|
if x_end < width / 2 && y_end < height / 2 {
|
|
q1 += 1;
|
|
} else if x_end > width / 2 && y_end < height / 2 {
|
|
q2 += 1;
|
|
} else if x_end < width / 2 && y_end > height / 2 {
|
|
q3 += 1;
|
|
} else if x_end > width / 2 && y_end > height / 2 {
|
|
q4 += 1;
|
|
}
|
|
}
|
|
|
|
q1 * q2 * q3 * q4
|
|
}
|
|
|
|
fn solve_2(input: &str, width: i64, height: i64) -> i64 {
|
|
let (_, mut robots) = parse(input).unwrap();
|
|
|
|
let mut min_e = i64::MAX;
|
|
let mut time = 0;
|
|
|
|
for t in 0..=100000 {
|
|
let (mut q1, mut q2, mut q3, mut q4) = (0, 0, 0, 0);
|
|
for (pos, vel) in robots.iter_mut() {
|
|
*pos = calc_pos(*pos, *vel, width, height, 1);
|
|
if pos.0 < width / 2 && pos.1 < height / 2 {
|
|
q1 += 1;
|
|
} else if pos.0 > width / 2 && pos.1 < height / 2 {
|
|
q2 += 1;
|
|
} else if pos.0 < width / 2 && pos.1 > height / 2 {
|
|
q3 += 1;
|
|
} else if pos.0 > width / 2 && pos.1 > height / 2 {
|
|
q4 += 1;
|
|
}
|
|
}
|
|
|
|
let e = q1 * q2 * q3 * q4;
|
|
if min_e > e {
|
|
time = t;
|
|
min_e = e;
|
|
}
|
|
}
|
|
|
|
time + 1
|
|
}
|
|
|
|
fn main() {
|
|
println!("Hello, this is Patrick!");
|
|
|
|
let input = include_str!("../input.txt");
|
|
|
|
let result_1 = solve_1(input, 101, 103);
|
|
println!("The safety factor will be {}", result_1);
|
|
|
|
let result_2 = solve_2(input, 101, 103);
|
|
println!("The time that the easter egg occurs is {}s", result_2);
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_1() {
|
|
let test_input = include_str!("../test.txt");
|
|
assert_eq!(solve_1(test_input, 11, 7), 12);
|
|
}
|
|
|
|
//#[test]
|
|
//fn test_2() {
|
|
// //let test_input = include_str!("../test.txt");
|
|
// //assert_eq!(solve_2(test_input), _);
|
|
//}
|
|
}
|