Skip to content

Commit

Permalink
Day 8: Resonant Collinearity
Browse files Browse the repository at this point in the history
  • Loading branch information
ephemient committed Dec 8, 2024
1 parent a10526c commit f34e61c
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ Development occurs in language-specific directories:
|[Day5.hs](hs/src/Day5.hs)|[Day5.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day5.kt)|[day5.py](py/aoc2024/day5.py)|[day5.rs](rs/src/day5.rs)|
|[Day6.hs](hs/src/Day6.hs)|[Day6.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day6.kt)|[day6.py](py/aoc2024/day6.py)|[day6.rs](rs/src/day6.rs)|
|[Day7.hs](hs/src/Day7.hs)|[Day7.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day7.kt)|[day7.py](py/aoc2024/day7.py)|[day7.rs](rs/src/day7.rs)|
|[Day8.hs](hs/src/Day8.hs)|[Day8.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day8.kt)|[day8.py](py/aoc2024/day8.py)||
|[Day8.hs](hs/src/Day8.hs)|[Day8.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day8.kt)|[day8.py](py/aoc2024/day8.py)|[day8.rs](rs/src/day8.rs)|
8 changes: 7 additions & 1 deletion rs/benches/criterion.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use aoc2024::{day1, day2, day3, day4, day5, day6, day7};
use aoc2024::{day1, day2, day3, day4, day5, day6, day7, day8};
use criterion::{black_box, Criterion};
use std::env;
use std::fs;
Expand Down Expand Up @@ -56,6 +56,12 @@ fn aoc2024_bench(c: &mut Criterion) -> io::Result<()> {
g.bench_function("part 2", |b| b.iter(|| day7::part2(black_box(&data))));
g.finish();

let data = get_day_input(8)?;
let mut g = c.benchmark_group("day 8");
g.bench_function("part 1", |b| b.iter(|| day8::part1(black_box(&data))));
g.bench_function("part 2", |b| b.iter(|| day8::part2(black_box(&data))));
g.finish();

Ok(())
}

Expand Down
90 changes: 90 additions & 0 deletions rs/src/day8.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use std::collections::BTreeSet;
use std::iter;

use itertools::Itertools;

fn solve<I>(data: &str, multiples: I) -> usize
where
I: Clone + Iterator<Item = isize>,
{
let (mut height, mut width) = (0, 0);
data.lines()
.enumerate()
.flat_map(|(y, line)| {
height = y + 1;
width = width.max(line.len());
line.bytes().enumerate().filter_map(move |(x, b)| match b {
b'.' => None,
_ => Some((b, (y, x))),
})
})
.into_grouping_map_by(|(b, _)| *b)
.fold_with(
|_, _| vec![],
|mut acc, _, (_, point)| {
acc.push(point);
acc
},
)
.values()
.flat_map(|points| {
points.iter().flat_map(|point0 @ (y0, x0)| {
points
.iter()
.filter(move |point1| point0 != *point1)
.flat_map(|(y1, x1)| {
let (dy, dx) = (*y1 as isize - *y0 as isize, *x1 as isize - *x0 as isize);
multiples
.clone()
.map(move |i| {
y1.checked_add_signed(i * dy)
.filter(|y| *y < height)
.zip(x1.checked_add_signed(i * dx).filter(|x| *x < width))
})
.while_some()
})
})
})
.collect::<BTreeSet<_>>()
.len()
}

pub fn part1(data: &str) -> usize {
solve(data, iter::once(1))
}

pub fn part2(data: &str) -> usize {
solve(data, iter::successors(Some(0), |i| Some(i + 1)))
}

#[cfg(test)]
mod tests {
use super::*;
use indoc::indoc;
use pretty_assertions::assert_eq;

static EXAMPLE: &str = indoc! {"
............
........0...
.....0......
.......0....
....0.......
......A.....
............
............
........A...
.........A..
............
............
"};

#[test]
fn part1_examples() {
assert_eq!(14, part1(EXAMPLE));
}

#[test]
fn part2_examples() {
assert_eq!(34, part2(EXAMPLE));
}
}
1 change: 1 addition & 0 deletions rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ pub mod day4;
pub mod day5;
pub mod day6;
pub mod day7;
pub mod day8;
10 changes: 9 additions & 1 deletion rs/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use anyhow::anyhow;
use aoc2024::{day1, day2, day3, day4, day5, day6, day7};
use aoc2024::{day1, day2, day3, day4, day5, day6, day7, day8};
use std::collections::HashSet;
use std::env;
use std::fs;
Expand Down Expand Up @@ -73,5 +73,13 @@ fn main() -> anyhow::Result<()> {
println!();
}

if args.is_empty() || args.contains("8") {
println!("Day 8");
let data = get_day_input(8)?;
println!("{:?}", day8::part1(&data));
println!("{:?}", day8::part2(&data));
println!();
}

Ok(())
}

0 comments on commit f34e61c

Please sign in to comment.