Skip to content

Commit

Permalink
Merge pull request #79 from ephemient/rs/day10
Browse files Browse the repository at this point in the history
  • Loading branch information
ephemient authored Dec 10, 2024
2 parents fc9a2f5 + 74dd02b commit edd7ef2
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ Development occurs in language-specific directories:
|[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.rs](rs/src/day8.rs)|
|[Day9.hs](hs/src/Day9.hs)|[Day9.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day9.kt)|[day9.py](py/aoc2024/day9.py)|[day9.rs](rs/src/day9.rs)|
|[Day10.hs](hs/src/Day10.hs)|[Day10.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day10.kt)|[day10.py](py/aoc2024/day10.py)||
|[Day10.hs](hs/src/Day10.hs)|[Day10.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day10.kt)|[day10.py](py/aoc2024/day10.py)|[day10.rs](rs/src/day10.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, day8, day9};
use aoc2024::{day1, day10, day2, day3, day4, day5, day6, day7, day8, day9};
use criterion::{black_box, Criterion};
use std::env;
use std::fs;
Expand Down Expand Up @@ -68,6 +68,12 @@ fn aoc2024_bench(c: &mut Criterion) -> io::Result<()> {
g.bench_function("part 2", |b| b.iter(|| day9::part2(black_box(&data))));
g.finish();

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

Ok(())
}

Expand Down
100 changes: 100 additions & 0 deletions rs/src/day10.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use std::array;
use std::collections::{BTreeMap, BTreeSet};

fn parse(data: &str) -> [BTreeSet<(usize, usize)>; 10] {
let mut elevations = array::from_fn(|_| BTreeSet::new());
for (y, line) in data.lines().enumerate() {
for (x, c) in line.char_indices() {
if let Some(h) = c.to_digit(10) {
elevations[h as usize].insert((y, x));
}
}
}
elevations
}

fn step<T, F>(
acc: &BTreeMap<(usize, usize), T>,
points: &BTreeSet<(usize, usize)>,
plus: F,
) -> BTreeMap<(usize, usize), T>
where
T: Clone,
F: Fn(&T, &T) -> T,
{
let mut ret = BTreeMap::new();
for ((y, x), value) in acc {
for (dy, dx) in [(-1, 0), (0, -1), (0, 1), (1, 0)] {
if let Some(point) = y
.checked_add_signed(dy)
.zip(x.checked_add_signed(dx))
.filter(|point| points.contains(point))
{
ret.entry(point)
.and_modify(|e: &mut T| *e = plus(value, e))
.or_insert_with(|| value.clone());
}
}
}
ret
}

pub fn part1(data: &str) -> usize {
let elevations = parse(data);
elevations[1..]
.iter()
.fold(
elevations[0]
.iter()
.map(|point| (*point, [*point].into_iter().collect()))
.collect(),
|acc, points| {
step(&acc, points, |x, y| -> BTreeSet<_> {
x.union(y).copied().collect()
})
},
)
.values()
.map(|value| value.len())
.sum()
}

pub fn part2(data: &str) -> usize {
let elevations = parse(data);
elevations[1..]
.iter()
.fold(
elevations[0].iter().map(|point| (*point, 1usize)).collect(),
|acc, points| step(&acc, points, |x, y| x + y),
)
.values()
.sum()
}

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

static EXAMPLE: &str = indoc! {"
89010123
78121874
87430965
96549874
45678903
32019012
01329801
10456732
"};

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

#[test]
fn part2_examples() {
assert_eq!(81, part2(EXAMPLE));
}
}
1 change: 1 addition & 0 deletions rs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod day1;
pub mod day10;
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,5 +1,5 @@
use anyhow::anyhow;
use aoc2024::{day1, day2, day3, day4, day5, day6, day7, day8, day9};
use aoc2024::{day1, day10, day2, day3, day4, day5, day6, day7, day8, day9};
use std::collections::HashSet;
use std::env;
use std::fs;
Expand Down Expand Up @@ -89,5 +89,13 @@ fn main() -> anyhow::Result<()> {
println!();
}

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

Ok(())
}

0 comments on commit edd7ef2

Please sign in to comment.