day14
This commit is contained in:
parent
f9c32f0022
commit
f87e5ea0af
|
@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue