summaryrefslogtreecommitdiff
path: root/2023/src
diff options
context:
space:
mode:
authorJustin Wernick <justin@worthe-it.co.za>2023-12-24 13:53:00 +0200
committerJustin Wernick <justin@worthe-it.co.za>2023-12-24 13:53:00 +0200
commitf3304cff3fc3614a691539c3174980a02f72f19a (patch)
tree3c180792f984829be9bc48e462710d72816abf9b /2023/src
parentef82c8d175f44a1d8b7cf7f5e0fffe9159fae74b (diff)
Day 24 part 1
Diffstat (limited to '2023/src')
-rw-r--r--2023/src/bin/day_24.rs95
1 files changed, 87 insertions, 8 deletions
diff --git a/2023/src/bin/day_24.rs b/2023/src/bin/day_24.rs
index b3a610b..325b4cc 100644
--- a/2023/src/bin/day_24.rs
+++ b/2023/src/bin/day_24.rs
@@ -1,19 +1,98 @@
-use nom::IResult;
+use nalgebra::{Matrix2, Point2, Point3, Vector2, Vector3};
+use nom::{
+ bytes::complete::tag,
+ character::complete::{i64, line_ending},
+ combinator::map,
+ multi::separated_list1,
+ sequence::{separated_pair, tuple},
+ IResult,
+};
use std::fs;
fn main() -> Result<(), Box<dyn std::error::Error>> {
- let input = fs::read_to_string("inputs/day_2.txt")?;
- let parsed = Example::parser(&input).unwrap().1;
- dbg!(&parsed);
+ let input = fs::read_to_string("inputs/day_24.txt")?;
+ let parsed = Hailstones::parser(&input).unwrap().1;
+ dbg!(&parsed.count_intersections_2d(200000000000000., 400000000000000.));
Ok(())
}
#[derive(Debug)]
-struct Example;
+struct Hailstones(Vec<Hailstone>);
-impl Example {
- fn parser(_input: &str) -> IResult<&str, Self> {
- todo!()
+#[derive(Debug)]
+struct Hailstone {
+ initial_position: Point3<f64>,
+ velocity: Vector3<f64>,
+}
+
+impl Hailstones {
+ fn parser(input: &str) -> IResult<&str, Self> {
+ map(separated_list1(line_ending, Hailstone::parser), Hailstones)(input)
+ }
+
+ fn count_intersections_2d(&self, min: f64, max: f64) -> usize {
+ self.0
+ .iter()
+ .enumerate()
+ .map(|(i, hailstone)| {
+ self.0
+ .iter()
+ .skip(i + 1)
+ .filter(|other_hailstone| hailstone.intersects_2d(other_hailstone, min, max))
+ .count()
+ })
+ .sum()
+ }
+}
+
+impl Hailstone {
+ fn parser(input: &str) -> IResult<&str, Self> {
+ map(
+ separated_pair(
+ map(
+ tuple((i64, tag(", "), i64, tag(", "), i64)),
+ |(x, _, y, _, z)| Point3::new(x as f64, y as f64, z as f64),
+ ),
+ tag(" @ "),
+ map(
+ tuple((i64, tag(", "), i64, tag(", "), i64)),
+ |(x, _, y, _, z)| Vector3::new(x as f64, y as f64, z as f64),
+ ),
+ ),
+ |(initial_position, velocity)| Hailstone {
+ initial_position,
+ velocity,
+ },
+ )(input)
+ }
+
+ fn intersects_2d(&self, other: &Hailstone, min: f64, max: f64) -> bool {
+ let variables = Matrix2::new(
+ self.velocity.x,
+ -other.velocity.x,
+ self.velocity.y,
+ -other.velocity.y,
+ );
+ let constants = Vector2::new(
+ other.initial_position.x - self.initial_position.x,
+ other.initial_position.y - self.initial_position.y,
+ );
+
+ if let Some(variables_inverse) = variables.try_inverse() {
+ let intersection = variables_inverse * constants;
+ let self_t = intersection.x;
+ let other_t = intersection.y;
+
+ let intersection = self.initial_position.xy() + self.velocity.xy() * self_t;
+ self_t >= 0.
+ && other_t >= 0.
+ && intersection.x >= min
+ && intersection.x <= max
+ && intersection.y >= min
+ && intersection.y <= max
+ } else {
+ false
+ }
}
}