Skip to content

Commit

Permalink
Day 11: Cosmic Expansion
Browse files Browse the repository at this point in the history
  • Loading branch information
ephemient committed Dec 11, 2023
1 parent e39af65 commit 0f3fcd9
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ Development occurs in language-specific directories:
|[Day8.hs](hs/src/Day8.hs)|[Day8.kt](kt/aoc2023-lib/src/commonMain/kotlin/com/github/ephemient/aoc2023/Day8.kt)|[day8.py](py/aoc2023/day8.py)|[day8.rs](rs/src/day8.rs)|
|[Day9.hs](hs/src/Day9.hs)|[Day9.kt](kt/aoc2023-lib/src/commonMain/kotlin/com/github/ephemient/aoc2023/Day9.kt)|[day9.py](py/aoc2023/day9.py)|[day9.rs](rs/src/day9.rs)|
|[Day10.hs](hs/src/Day10.hs)|[Day10.kt](kt/aoc2023-lib/src/commonMain/kotlin/com/github/ephemient/aoc2023/Day10.kt)|[day10.py](py/aoc2023/day10.py)|[day10.rs](rs/src/day10.rs)|
|[Day11.hs](hs/src/Day11.hs)|[Day11.kt](kt/aoc2023-lib/src/commonMain/kotlin/com/github/ephemient/aoc2023/Day11.kt)|[day11.py](py/aoc2023/day11.py)||
|[Day11.hs](hs/src/Day11.hs)|[Day11.kt](kt/aoc2023-lib/src/commonMain/kotlin/com/github/ephemient/aoc2023/Day11.kt)|[day11.py](py/aoc2023/day11.py)|[day11.rs](rs/src/day11.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 aoc2023::{day1, day10, day2, day3, day4, day5, day6, day7, day8, day9};
use aoc2023::{day1, day10, day11, day2, day3, day4, day5, day6, day7, day8, day9};
use criterion::{black_box, Criterion};
use std::env;
use std::fs;
Expand Down Expand Up @@ -74,6 +74,12 @@ fn aoc2023_bench(c: &mut Criterion) -> io::Result<()> {
g.bench_function("part 2", |b| b.iter(|| day10::part2(black_box(&data))));
g.finish();

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

Ok(())
}

Expand Down
85 changes: 85 additions & 0 deletions rs/src/day11.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
fn solve(data: &str, n: u64) -> u64 {
let lines = data.lines().collect::<Vec<_>>();
let rows = lines
.iter()
.enumerate()
.filter_map(|(y, line)| {
if line.chars().any(|c| c == '#') {
None
} else {
Some(y)
}
})
.collect::<Vec<_>>();
let cols = (0..lines
.iter()
.map(|line| line.len())
.max()
.unwrap_or_default())
.filter(|&x| lines.iter().all(|line| !line[x..].starts_with('#')))
.collect::<Vec<_>>();
let galaxies = lines
.iter()
.enumerate()
.flat_map(|(y, line)| {
line.char_indices()
.filter_map(move |(x, c)| if c == '#' { Some((y, x)) } else { None })
})
.collect::<Vec<_>>();
galaxies
.iter()
.enumerate()
.flat_map(|(i, (y0, x0))| {
let rows = &rows;
let cols = &cols;
galaxies[i + 1..].iter().map(move |(y1, x1)| {
let (x0, x1) = (x0.min(x1), x0.max(x1));
(y1 - y0 + x1 - x0) as u64
+ (n - 1)
* (rows.binary_search(y1).unwrap_err()
- rows.binary_search(y0).unwrap_err()
+ cols.binary_search(x1).unwrap_err()
- cols.binary_search(x0).unwrap_err()) as u64
})
})
.sum()
}

pub fn part1(data: &str) -> u64 {
solve(data, 2)
}

pub fn part2(data: &str) -> u64 {
solve(data, 1000000)
}

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

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

#[test]
fn part1_examples() {
assert_eq!(374, solve(EXAMPLE, 2));
}

#[test]
fn part2_examples() {
assert_eq!(1030, solve(EXAMPLE, 10));
assert_eq!(8410, solve(EXAMPLE, 100));
}
}
1 change: 1 addition & 0 deletions rs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod day1;
pub mod day10;
pub mod day11;
pub mod day2;
pub mod day3;
pub mod day4;
Expand Down
10 changes: 9 additions & 1 deletion rs/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use aoc2023::{day1, day10, day2, day3, day4, day5, day6, day7, day8, day9};
use aoc2023::{day1, day10, day11, day2, day3, day4, day5, day6, day7, day8, day9};
use std::collections::HashSet;
use std::env;
use std::fs;
Expand Down Expand Up @@ -96,5 +96,13 @@ fn main() -> io::Result<()> {
println!();
}

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

Ok(())
}

0 comments on commit 0f3fcd9

Please sign in to comment.