70 lines
1.9 KiB
Rust
70 lines
1.9 KiB
Rust
#![feature(drain_filter)]
|
|
#![feature(test)]
|
|
extern crate test;
|
|
use aoc2021::{
|
|
common::*,
|
|
grid::{Grid, PositionND, VecGrid},
|
|
};
|
|
use itertools::Itertools;
|
|
|
|
const DAY: usize = 15;
|
|
type Parsed = VecGrid<u8>;
|
|
|
|
fn parse_input(raw: &str) -> Parsed {
|
|
VecGrid::from_bytes_2d(raw, |b| b - b'0')
|
|
}
|
|
|
|
// I win the award for slowest solution, at least.
|
|
fn part1(parsed: &Parsed, grid_size: usize) -> usize {
|
|
let mut paths = vec![(PositionND::from([0, 0]), 0)];
|
|
let end = PositionND::from([grid_size - 1, grid_size - 1]);
|
|
let mut max_risk = 0usize;
|
|
loop {
|
|
let min_index = paths.iter().position_min_by_key(|(_, c)| c).unwrap();
|
|
let (next_candidate, risk_so_far) = paths.swap_remove(min_index);
|
|
for (risk, position) in next_candidate.neighbors_no_diagonals().into_iter().filter_map(|p| parsed.get(&p).zip(Some(p))) {
|
|
let new_risk = risk_so_far + *risk as usize;
|
|
max_risk = max_risk.max(new_risk);
|
|
paths.push((position, new_risk));
|
|
}
|
|
paths.sort_unstable_by_key(|(p, _)| p.points[0] as usize * grid_size + p.points[1] as usize);
|
|
paths = paths.into_iter().coalesce(|(p, r), (p2, r2)| if p == p2 { Ok((p, r.min(r2))) } else { Err(((p, r), (p2, r2))) }).collect();
|
|
if let Some((_, risk)) = paths.iter().filter(|(p, _)| p == &end).min_by_key(|(_, r)| r) {
|
|
return *risk;
|
|
}
|
|
}
|
|
}
|
|
|
|
fn part2(parsed: &Parsed) -> usize {
|
|
unimplemented!()
|
|
}
|
|
|
|
fn main() {
|
|
let input = parse_input(&read_file(DAY));
|
|
println!("Part 1: {}", part1(&input, 100));
|
|
println!("Part 2: {}", part2(&input));
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use aoc2021::*;
|
|
|
|
const TEST_INPUT: &str = "1163751742
|
|
1381373672
|
|
2136511328
|
|
3694931569
|
|
7463417111
|
|
1319128137
|
|
1359912421
|
|
3125421639
|
|
1293138521
|
|
2311944581";
|
|
|
|
test!(part1(10) == 40);
|
|
test!(part2() == 0);
|
|
bench!(part1(100) == 656);
|
|
bench!(part2() == 0);
|
|
bench_input!(VecGrid::len => 100);
|
|
}
|