From f87e5ea0af2f1d881d8aeb29f135dea1dc341a9d Mon Sep 17 00:00:00 2001 From: Jan-Bulthuis Date: Sat, 14 Dec 2024 18:10:45 +0100 Subject: [PATCH] day14 --- aoc_2024/src/day14.rs | 128 ++++++++++++++++++++++++++++++++++++++++++ aoc_2024/src/lib.rs | 1 + 2 files changed, 129 insertions(+) create mode 100644 aoc_2024/src/day14.rs diff --git a/aoc_2024/src/day14.rs b/aoc_2024/src/day14.rs new file mode 100644 index 0000000..eb5e3b8 --- /dev/null +++ b/aoc_2024/src/day14.rs @@ -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::() + / 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 + ); + } +} diff --git a/aoc_2024/src/lib.rs b/aoc_2024/src/lib.rs index cddd5fc..fbe7cda 100644 --- a/aoc_2024/src/lib.rs +++ b/aoc_2024/src/lib.rs @@ -3,6 +3,7 @@ mod day10; mod day11; mod day12; mod day13; +mod day14; mod day2; mod day3; mod day4;