Skip to content

Commit

Permalink
Day 24a
Browse files Browse the repository at this point in the history
  • Loading branch information
lpenz committed Dec 24, 2023
1 parent dd606e9 commit d145b26
Show file tree
Hide file tree
Showing 7 changed files with 446 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
- day21
- day22
- day23
- day24
# end
if: github.ref == 'refs/heads/main'
needs: [ omnilint, rust ]
Expand Down
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ members = [
"day21",
"day22",
"day23",
"day24",
]

9 changes: 9 additions & 0 deletions day24/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "day24"
version = "0.1.0"
edition = "2021"

[dependencies]
aoc = { path = "../aoc" }
color-eyre = "0.6.2"
nom = "7.1.3"
300 changes: 300 additions & 0 deletions day24/input.txt

Large diffs are not rendered by default.

69 changes: 69 additions & 0 deletions day24/src/bin/day24a.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (C) 2023 Leandro Lisboa Penz <lpenz@lpenz.org>
// This file is subject to the terms and conditions defined in
// file 'LICENSE', which is part of this source code package.

use day24::*;

fn intercept(v: Stone, u: Stone) -> Option<Xyz> {
let (pos_v, vel_v, _) = v;
let (pos_u, vel_u, _) = u;
let a = vel_v.1 / vel_v.0;
let b = vel_u.1 / vel_u.0;
let c = pos_v.1 - pos_v.0 * a;
let d = pos_u.1 - pos_u.0 * b;
if a == b {
return None;
}
let x = (d - c) / (a - b);
let y = a * x + c;
let t_v = (x - pos_v.0) / vel_v.0;
if t_v < 0_f64 {
return None;
}
let t_u = (x - pos_u.0) / vel_u.0;
if t_u < 0_f64 {
return None;
}
Some((x, y, 0_f64))
}

fn process(tl: Xyz, br: Xyz, bufin: impl BufRead) -> Result<usize> {
let stones = parser::parse(bufin)?;
Ok((0..stones.len() - 1)
.flat_map(|i| {
let stones = &stones;
(i + 1..stones.len()).filter(move |&j| {
let a = stones[i];
let b = stones[j];
if let Some(c) = intercept(a, b) {
c.0 >= tl.0 && c.0 <= br.0 && c.1 >= tl.1 && c.1 <= br.1
} else {
false
}
})
})
.count())
}

#[test]
fn test() -> Result<()> {
assert_eq!(
process(
(7_f64, 7_f64, 0_f64),
(27_f64, 27_f64, 0_f64),
EXAMPLE.as_bytes()
)?,
2
);
Ok(())
}

fn main() -> Result<()> {
do_main(|| {
process(
(200000000000000_f64, 200000000000000_f64, 0_f64),
(400000000000000_f64, 400000000000000_f64, 0_f64),
stdin().lock(),
)
})
}
57 changes: 57 additions & 0 deletions day24/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (C) 2023 Leandro Lisboa Penz <lpenz@lpenz.org>
// This file is subject to the terms and conditions defined in
// file 'LICENSE', which is part of this source code package.

pub use aoc::*;

pub const EXAMPLE: &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
";

pub type Xyz = (f64, f64, f64);
pub type Stone = (Xyz, Xyz, usize);

pub mod parser {
use aoc::parser::*;

use super::*;

fn xyz(input: &str) -> IResult<&str, Xyz> {
let (input, x) = character::i64(input)?;
let (input, _) = tag(",")(input)?;
let (input, _) = character::space1(input)?;
let (input, y) = character::i64(input)?;
let (input, _) = tag(",")(input)?;
let (input, _) = character::space1(input)?;
let (input, z) = character::i64(input)?;
Ok((input, (x as f64, y as f64, z as f64)))
}

fn line(input: &str) -> IResult<&str, Stone> {
let (input, pos) = xyz(input)?;
let (input, _) = tag(" @")(input)?;
let (input, _) = character::space1(input)?;
let (input, vel) = xyz(input)?;
let (input, _) = character::newline(input)?;
Ok((input, (pos, vel, 0)))
}

pub fn parse(mut bufin: impl BufRead) -> Result<Vec<Stone>> {
let input: Result<Vec<Stone>> = aoc::parse_with!(multi::many1(line), bufin);
Ok(input?
.into_iter()
.enumerate()
.map(|(i, v)| (v.0, v.1, i))
.collect::<Vec<_>>())
}
}

#[test]
fn test() -> Result<()> {
let input = parser::parse(EXAMPLE.as_bytes())?;
assert_eq!(input.len(), 5);
Ok(())
}

0 comments on commit d145b26

Please sign in to comment.