day-24 part 1 done
This commit is contained in:
9
2023/Cargo.lock
generated
9
2023/Cargo.lock
generated
@@ -241,6 +241,15 @@ dependencies = [
|
|||||||
"petgraph",
|
"petgraph",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day-24"
|
||||||
|
version = "2023.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"glam",
|
||||||
|
"itertools",
|
||||||
|
"nom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "day-3"
|
name = "day-3"
|
||||||
version = "2023.0.0"
|
version = "2023.0.0"
|
||||||
|
|||||||
13
2023/day-24/Cargo.toml
Normal file
13
2023/day-24/Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[package]
|
||||||
|
name = "day-24"
|
||||||
|
version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
authors.workspace = true
|
||||||
|
repository.workspace = true
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
nom = { workspace = true }
|
||||||
|
itertools = {workspace = true }
|
||||||
|
glam.workspace = true
|
||||||
4
2023/day-24/src/lib.rs
Normal file
4
2023/day-24/src/lib.rs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
pub mod part1;
|
||||||
|
pub use crate::part1::*;
|
||||||
|
pub mod part2;
|
||||||
|
pub use crate::part2::*;
|
||||||
12
2023/day-24/src/main.rs
Normal file
12
2023/day-24/src/main.rs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#![warn(clippy::all, clippy::pedantic)]
|
||||||
|
|
||||||
|
use day_24::part1;
|
||||||
|
use day_24::part2;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = include_str!("./input.txt");
|
||||||
|
let part1_result = part1(input, 200_000_000_000_000.0, 400_000_000_000_000.0);
|
||||||
|
println!("part 1: {part1_result}");
|
||||||
|
let part2_result = part2(input);
|
||||||
|
println!("part 2: {part2_result}");
|
||||||
|
}
|
||||||
93
2023/day-24/src/part1.rs
Normal file
93
2023/day-24/src/part1.rs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#![warn(clippy::all, clippy::pedantic)]
|
||||||
|
|
||||||
|
use glam::DVec3;
|
||||||
|
use nom::{
|
||||||
|
bytes::complete::tag,
|
||||||
|
character::complete,
|
||||||
|
multi::separated_list1,
|
||||||
|
sequence::{separated_pair, tuple},
|
||||||
|
IResult, Parser, number,
|
||||||
|
};
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
struct Stones {
|
||||||
|
pub start: DVec3,
|
||||||
|
pub velocity: DVec3,
|
||||||
|
}
|
||||||
|
impl Stones {
|
||||||
|
fn cross(&self, other: &Self) -> Option<DVec3> {
|
||||||
|
// x1 + v_x1 *t = x_n
|
||||||
|
// t= (x_n - x_1)/v_x1
|
||||||
|
// (y_n - y_1)/v_y1 = (x_n - x_1)/v_x1
|
||||||
|
// y_n = v_y1 * (x_n -x_1)/v_x1 + y_1
|
||||||
|
// (v_y1/v_x1) * x_n - x_1 * (v_y1/v_x1) + y_1 = (v_y2/v_x2) * x_n -x_2 * (v_y2/v_x2) + y_2
|
||||||
|
// x_n * ((v_y1/v_x1) - (v_y2/v_x2)) = x_1 * (v_y1/v_x1) - x_2 * (v_y2/v_x2) + y_2 - y_1
|
||||||
|
// x1 + v1 *t == x2 + v2*t
|
||||||
|
// (x1-x2)/(v2-v1) = t
|
||||||
|
let slope1 = self.velocity.y / self.velocity.x;
|
||||||
|
let slope2 = other.velocity.y / other.velocity.x;
|
||||||
|
let denom = slope1 - slope2;
|
||||||
|
let x = (self.start.x *slope1 -other.start.x *slope2 + other.start.y - self.start.y) / denom;
|
||||||
|
let y = slope1 * (x - self.start.x) + self.start.y;
|
||||||
|
if !x.is_finite() || !y.is_finite() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let t1 = (x - self.start.x) / self.velocity.x;
|
||||||
|
let t2 = (x - other.start.x) / other.velocity.x;
|
||||||
|
if t1 < 0.0 || t2 < 0.0{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(DVec3::new(x, y, 0.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn part1(input: &str, min:f64, max:f64) -> String {
|
||||||
|
let (_, stones) = parse_input(input).expect("Aoc should have valid input");
|
||||||
|
stones.iter().combinations(2)
|
||||||
|
.filter_map(|pair| {
|
||||||
|
let [a,b] = pair[..] else { return None};
|
||||||
|
a.cross(b).and_then(|cross_position| (cross_position.x <= max && cross_position.y <= max && cross_position.x >= min && cross_position.y >= min).then_some(cross_position) )
|
||||||
|
}).count().to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_tuple(input: &str) -> IResult<&str, DVec3> {
|
||||||
|
let (input, x) = number::complete::double(input)?;
|
||||||
|
let (input, _) = tuple((tag(","), complete::space0))(input)?;
|
||||||
|
let (input, y) = number::complete::double(input)?;
|
||||||
|
let (input, _) = tuple((tag(","), complete::space0))(input)?;
|
||||||
|
let (input, z) = number::complete::double(input)?;
|
||||||
|
Ok((input, DVec3::new(x, y, z)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_input(input: &str) -> IResult<&str, Vec<Stones>> {
|
||||||
|
separated_list1(
|
||||||
|
complete::line_ending,
|
||||||
|
separated_pair(
|
||||||
|
parse_tuple,
|
||||||
|
tuple((complete::space0, tag("@"), complete::space0)),
|
||||||
|
parse_tuple,
|
||||||
|
)
|
||||||
|
.map(|(start, velocity)| Stones { start, velocity }),
|
||||||
|
)(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const INPUT: &str = "19, 13, 30 @ -2, 1, -2
|
||||||
|
18, 19, 22 @ -1, -1, -2
|
||||||
|
20, 25, 34 @ -2, -2, -4
|
||||||
|
12, 31, 28 @ -1, -2, -1
|
||||||
|
20, 19, 15 @ 1, -5, -3";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_works() {
|
||||||
|
let result = part1(INPUT, 7.0, 27.0);
|
||||||
|
assert_eq!(result, "2".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
20
2023/day-24/src/part2.rs
Normal file
20
2023/day-24/src/part2.rs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#![warn(clippy::all, clippy::pedantic)]
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn part2 (_input: &str) -> String {
|
||||||
|
"Not Finished".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const INPUT: &str = "";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_works() {
|
||||||
|
let result = part2(INPUT);
|
||||||
|
assert_eq!(result, "Not Finished".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user