This commit is contained in:
Jan-Bulthuis 2024-12-14 18:10:45 +01:00
parent f9c32f0022
commit f87e5ea0af
2 changed files with 129 additions and 0 deletions

128
aoc_2024/src/day14.rs Normal file
View File

@ -0,0 +1,128 @@
use std::sync::OnceLock;
use aoc_runner_derive::{aoc, aoc_generator};
use nom::{
bytes::complete::tag,
character::complete::{i64 as parse_i64, newline, space1},
error::Error,
multi::separated_list0,
sequence::{preceded, separated_pair},
};
type Input = Vec<((i64, i64), (i64, i64))>;
#[aoc_generator(day14)]
fn parse(input: &str) -> Input {
separated_list0(
newline::<&str, Error<&str>>,
separated_pair(
preceded(tag("p="), separated_pair(parse_i64, tag(","), parse_i64)),
space1,
preceded(tag("v="), separated_pair(parse_i64, tag(","), parse_i64)),
),
)(input)
.unwrap()
.1
}
#[aoc(day14, part1)]
fn part1(input: &Input) -> i64 {
#[cfg(test)]
let (w, h) = (7, 11);
#[cfg(not(test))]
let (w, h) = (101, 103);
let mut quadrants = [0, 0, 0, 0];
input.iter().copied().for_each(|(p, v)| {
let (px, py) = (p.0, p.1);
let (vx, vy) = (v.0 + w, v.1 + h);
let (ex, ey) = ((px + vx * 100) % w, (py + vy * 100) % h);
if ex < w / 2 && ey < h / 2 {
quadrants[0] += 1;
} else if ex > (w - 1) / 2 && ey < h / 2 {
quadrants[1] += 1;
} else if ex < w / 2 && ey > (h - 1) / 2 {
quadrants[2] += 1;
} else if ex > (w - 1) / 2 && ey > (h - 1) / 2 {
quadrants[3] += 1;
}
});
quadrants.iter().product()
}
#[aoc(day14, part2)]
fn part2(input: &Input) -> usize {
let (w, h) = (101, 103);
let mut input = input.clone();
let mut iter = 0;
loop {
iter += 1;
let mut total = (0f64, 0f64);
input = input
.into_iter()
.map(|((px, py), (vx, vy))| {
let (px, py) = ((px + vx + w) % w, (py + vy + h) % h);
total.0 += px as f64;
total.1 += py as f64;
((px, py), (vx, vy))
})
.collect();
let mean = (total.0 / input.len() as f64, total.1 / input.len() as f64);
let variance = input
.iter()
.map(|((px, py), _)| {
let dx = *px as f64 - mean.0;
let dy = *py as f64 - mean.1;
dx * dx + dy * dy
})
.sum::<f64>()
/ input.len() as f64;
if variance < 1000.0 {
break;
}
}
iter
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn part1_example() {
assert_eq!(
part1(&parse(
"p=0,4 v=3,-3
p=6,3 v=-1,-3
p=10,3 v=-1,2
p=2,0 v=2,-1
p=0,0 v=1,3
p=3,0 v=-2,-2
p=7,6 v=-1,-3
p=3,0 v=-1,-2
p=9,3 v=2,3
p=7,3 v=-1,2
p=2,4 v=2,-3
p=9,5 v=-3,-3"
)),
12
);
}
#[test]
fn part2_example() {
assert_eq!(
part2(&parse(include_str!("../input/2024/day14.txt").trim_end())),
6398
);
}
}

View File

@ -3,6 +3,7 @@ mod day10;
mod day11; mod day11;
mod day12; mod day12;
mod day13; mod day13;
mod day14;
mod day2; mod day2;
mod day3; mod day3;
mod day4; mod day4;